From owner-freebsd-current@FreeBSD.ORG Mon Dec 15 14:02:33 2003 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 F245416A4CE for ; Mon, 15 Dec 2003 14:02:32 -0800 (PST) Received: from smtpzilla5.xs4all.nl (smtpzilla5.xs4all.nl [194.109.127.141]) by mx1.FreeBSD.org (Postfix) with ESMTP id C6A7F43D36 for ; Mon, 15 Dec 2003 14:02:28 -0800 (PST) (envelope-from wkb@freebie.xs4all.nl) Received: from freebie.xs4all.nl (freebie.xs4all.nl [213.84.32.253]) by smtpzilla5.xs4all.nl (8.12.9/8.12.9) with ESMTP id hBFM2RJ5029736 for ; Mon, 15 Dec 2003 23:02:27 +0100 (CET) Received: from freebie.xs4all.nl (localhost [127.0.0.1]) by freebie.xs4all.nl (8.12.10/8.12.9) with ESMTP id hBFM2Qhj014662 for ; Mon, 15 Dec 2003 23:02:26 +0100 (CET) (envelope-from wkb@freebie.xs4all.nl) Received: (from wkb@localhost) by freebie.xs4all.nl (8.12.10/8.12.9/Submit) id hBFM2QRM014661 for freebsd-current@freebsd.org; Mon, 15 Dec 2003 23:02:26 +0100 (CET) (envelope-from wkb) Resent-Message-Id: <200312152202.hBFM2QRM014661@freebie.xs4all.nl> Received: from maildrop9.xs4all.nl (maildrop9.xs4all.nl [194.109.127.229]) by freebie.xs4all.nl (8.12.9p1/8.12.9) with ESMTP id h9FNerPq098486 for ; Thu, 16 Oct 2003 01:40:53 +0200 (CEST) (envelope-from jkim@niksun.com) Received: from mxzilla8.xs4all.nl (mxzilla8.xs4all.nl [194.109.6.19]) by maildrop9.xs4all.nl (8.12.9/8.12.6) with ESMTP id h9FNernI096606 for ; Thu, 16 Oct 2003 01:40:53 +0200 (CEST) Received: from anuket.mj.niksun.com (gwnew.niksun.com [65.115.46.162]) by mxzilla8.xs4all.nl (8.12.10/8.12.10) with ESMTP id h9FNeqRM083924 for ; Thu, 16 Oct 2003 01:40:52 +0200 (CEST) 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 h9FNe5uv071092 for ; Wed, 15 Oct 2003 19:40:06 -0400 (EDT) (envelope-from jkim@niksun.com) X-RAV-AntiVirus: This e-mail has been scanned for viruses. From: Jung-uk Kim (by way of Jung-uk Kim ) Organization: Niksun, Inc. User-Agent: KMail/1.5.1 To: Wilko Bulte MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_Srdj/l1LSv6o5ys" Message-Id: <200310151940.02238.jkim@niksun.com> X-Spam-Status: No, hits=-5.6 required=2.0 tests=BAYES_10,EMAIL_ATTRIBUTION,PATCH_UNIFIED_DIFF, QUOTED_EMAIL_TEXT,UPPERCASE_25_50,USER_AGENT_KMAIL version=2.55 X-Spam-Level: X-Spam-Checker-Version: SpamAssassin 2.55 (1.174.2.19-2003-05-19-exp) Resent-From: wkb@freebie.xs4all.nl Resent-Date: Mon, 15 Dec 2003 23:02:26 +0100 Resent-To: freebsd-current@freebsd.org Subject: [PATCH] SysKonnect Yukon driver promiscuous mode 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: , Date: Mon, 15 Dec 2003 22:02:33 -0000 X-Original-Date: Wed, 15 Oct 2003 19:40:02 -0400 X-List-Received-Date: Mon, 15 Dec 2003 22:02:33 -0000 --Boundary-00=_Srdj/l1LSv6o5ys Content-Type: text/plain; charset="euc-kr" Content-Transfer-Encoding: 7bit Content-Disposition: inline I am re-sending it to your private e-mail just in case you missed @FreeBSD.Org e-mail. ;-) -------------- (I am CC'ing Nathan L. Binkert because my patch was originally from OpenBSD.) Here is the first patch for the bug. It is very simple to reproduce the bug. Run tcpdump on the interface, e.g., 'tcpdump -i sk0'. You will see all packets on the segment. While in promiscuous mode (i.e., don't quit tcpdump), try 'ifconfig down', e.g., 'ifconfig sk0 down', and bring it back up, e.g., 'ifconfig sk0 up'. You will only see your packets or broadcast packets. This bug also causes multicast filter to be cleaned up. This patch simplifies IFF_PROMISC checking from sk_ioctl() and prevents the inteface from getting re-initialized when you change other flags, e.g., arp. Thanks, JK PS: Actually I found another bug, which was originally from Bill Paul's code. I need more test but I will let you know. On Tuesday 14 October 2003 07:38 pm, Jung-uk Kim wrote: > I thought you were going to MFC it after 4.9-RELEASE but... > > Any way, I think you have to mention that miivar.h has partial MFC > from the following: > > http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/mii/miivar.h.diff >?r1=1.10&r2=1.11 > > Actually I got it from NetBSD. > > BTW, there is a buglet in the driver with promiscuous mode. ;-) > When the card is in promiscuous mode, trying changing any flags. > Promiscuous mode WILL not work properly because of a bug in the > original patch. > > Nathan also added checksum offloading feature recently. I am going > to add the feature, too. > > So stay tuned for more patches. ;-) > > Thanks, > > JK -- _______________________________________________________________ Jung-uk Kim NIKSUN, Inc. jkim@niksun.com http://www.niksun.com Tel: +1 732 821-5000 x3331 1100 Cornwall Road Fax: +1 732 821-6000 Monmouth Junction, NJ 08852 USA _______________________________________________________________ --Boundary-00=_Srdj/l1LSv6o5ys Content-Type: text/x-diff; charset="us-ascii"; name="sk-current.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="sk-current.diff" --- src/sys/pci/if_sk.c.orig Sat Sep 20 06:53:08 2003 +++ src/sys/pci/if_sk.c Wed Oct 15 19:10:32 2003 @@ -219,6 +219,7 @@ static u_int32_t sk_calchash (caddr_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 @@ -815,6 +816,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; @@ -1097,7 +1127,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; @@ -1115,34 +1144,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 { @@ -2242,12 +2249,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 { @@ -2289,6 +2290,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); @@ -2384,8 +2388,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) | @@ -2409,11 +2412,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=_Srdj/l1LSv6o5ys Content-Type: text/x-diff; charset="us-ascii"; name="sk-stable.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="sk-stable.diff" --- src/sys/pci/if_sk.c.orig Tue Oct 14 19:22:55 2003 +++ src/sys/pci/if_sk.c Wed Oct 15 18:58:12 2003 @@ -217,6 +217,7 @@ static u_int32_t sk_calchash __P((caddr_t)); static void sk_setfilt __P((struct sk_if_softc *, caddr_t, int)); static void sk_setmulti __P((struct sk_if_softc *)); +static void sk_setpromisc __P((struct sk_if_softc *)); #ifdef SK_USEIOSPACE #define SK_RES SYS_RES_IOPORT @@ -787,6 +788,34 @@ 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; { @@ -1125,7 +1154,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 s, error = 0; struct mii_data *mii; @@ -1147,34 +1175,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 +2264,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 +2305,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 +2403,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 +2427,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=_Srdj/l1LSv6o5ys--