If the interface is up and running, only modify the receive filter

when setting promiscuous or debug mode.  This avoids resetting the
chip unnecessarily.

Fixes PR kern/29126.
This commit is contained in:
kim 2005-02-06 03:15:14 +00:00
parent ad494d3b04
commit f045f7096d
5 changed files with 72 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: elinkxl.c,v 1.76 2005/02/04 02:10:36 perry Exp $ */
/* $NetBSD: elinkxl.c,v 1.77 2005/02/06 03:15:14 kim Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.76 2005/02/04 02:10:36 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: elinkxl.c,v 1.77 2005/02/06 03:15:14 kim Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -427,6 +427,7 @@ ex_config(sc)
ifp->if_stop = ex_stop;
ifp->if_flags =
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
sc->sc_if_flags = ifp->if_flags;
IFQ_SET_READY(&ifp->if_snd);
/*
@ -697,6 +698,7 @@ ex_init(ifp)
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
ex_start(ifp);
sc->sc_if_flags = ifp->if_flags;
GO_WINDOW(1);
@ -1382,7 +1384,21 @@ ex_ioctl(ifp, cmd, data)
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->ex_mii.mii_media, cmd);
break;
case SIOCSIFFLAGS:
/* If the interface is up and running, only modify the receive
* filter when setting promiscuous or debug mode. Otherwise
* fall through to ether_ioctl, which will reset the chip.
*/
#define RESETIGN (IFF_CANTCHANGE|IFF_DEBUG)
if (((ifp->if_flags & (IFF_UP|IFF_RUNNING))
== (IFF_UP|IFF_RUNNING))
&& ((ifp->if_flags & (~RESETIGN))
== (sc->sc_if_flags & (~RESETIGN)))) {
ex_set_mc(sc);
break;
#undef RESETIGN
}
/* FALLTHROUGH */
default:
error = ether_ioctl(ifp, cmd, data);
if (error == ENETRESET) {
@ -1397,6 +1413,7 @@ ex_ioctl(ifp, cmd, data)
break;
}
sc->sc_if_flags = ifp->if_flags;
splx(s);
return (error);
}
@ -1569,6 +1586,7 @@ ex_stop(ifp, disable)
ex_disable(sc);
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
sc->sc_if_flags = ifp->if_flags;
ifp->if_timer = 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: elinkxlvar.h,v 1.15 2005/02/04 02:10:36 perry Exp $ */
/* $NetBSD: elinkxlvar.h,v 1.16 2005/02/06 03:15:14 kim Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -137,6 +137,8 @@ struct ex_softc {
bus_dma_segment_t sc_useg, sc_dseg;
int sc_urseg, sc_drseg;
short sc_if_flags;
};
#define ex_waitcmd(sc) \

View File

@ -1,4 +1,4 @@
/* $NetBSD: tulip.c,v 1.132 2005/02/04 02:10:37 perry Exp $ */
/* $NetBSD: tulip.c,v 1.133 2005/02/06 03:15:14 kim Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2002 The NetBSD Foundation, Inc.
@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tulip.c,v 1.132 2005/02/04 02:10:37 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: tulip.c,v 1.133 2005/02/06 03:15:14 kim Exp $");
#include "bpfilter.h"
@ -497,6 +497,7 @@ tlp_attach(sc, enaddr)
strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
sc->sc_if_flags = ifp->if_flags;
ifp->if_ioctl = tlp_ioctl;
ifp->if_start = tlp_start;
ifp->if_watchdog = tlp_watchdog;
@ -1001,7 +1002,22 @@ tlp_ioctl(ifp, cmd, data)
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
break;
case SIOCSIFFLAGS:
/* If the interface is up and running, only modify the receive
* filter when setting promiscuous or debug mode. Otherwise
* fall through to ether_ioctl, which will reset the chip.
*/
#define RESETIGN (IFF_CANTCHANGE|IFF_DEBUG)
if (((ifp->if_flags & (IFF_UP|IFF_RUNNING))
== (IFF_UP|IFF_RUNNING))
&& ((ifp->if_flags & (~RESETIGN))
== (sc->sc_if_flags & (~RESETIGN)))) {
/* Set up the receive filter. */
(*sc->sc_filter_setup)(sc);
break;
#undef RESETIGN
}
/* FALLTHROUGH */
default:
error = ether_ioctl(ifp, cmd, data);
if (error == ENETRESET) {
@ -1021,6 +1037,7 @@ tlp_ioctl(ifp, cmd, data)
if (TULIP_IS_ENABLED(sc))
tlp_start(ifp);
sc->sc_if_flags = ifp->if_flags;
splx(s);
return (error);
}
@ -1930,6 +1947,7 @@ tlp_init(ifp)
*/
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
sc->sc_if_flags = ifp->if_flags;
out:
if (error) {
@ -2094,6 +2112,7 @@ tlp_stop(ifp, disable)
* Mark the interface down and cancel the watchdog timer.
*/
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
sc->sc_if_flags = ifp->if_flags;
ifp->if_timer = 0;
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: tulipvar.h,v 1.52 2005/02/04 02:10:37 perry Exp $ */
/* $NetBSD: tulipvar.h,v 1.53 2005/02/06 03:15:14 kim Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -450,6 +450,8 @@ struct tulip_softc {
struct tulip_txsq sc_txfreeq; /* free Tx descsofts */
struct tulip_txsq sc_txdirtyq; /* dirty Tx descsofts */
short sc_if_flags;
int sc_rxptr; /* next ready RX descriptor/descsoft */
#if NRND > 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_sip.c,v 1.97 2005/01/30 18:56:34 thorpej Exp $ */
/* $NetBSD: if_sip.c,v 1.98 2005/02/06 03:15:14 kim Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.97 2005/01/30 18:56:34 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.98 2005/02/06 03:15:14 kim Exp $");
#include "bpfilter.h"
#include "rnd.h"
@ -309,6 +309,8 @@ struct sip_softc {
struct sip_txsq sc_txfreeq; /* free Tx descsofts */
struct sip_txsq sc_txdirtyq; /* dirty Tx descsofts */
short sc_if_flags;
int sc_rxptr; /* next ready Rx descriptor/descsoft */
#if defined(DP83820)
int sc_rxdiscard;
@ -979,6 +981,7 @@ SIP_DECL(attach)(struct device *parent, struct device *self, void *aux)
strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
sc->sc_if_flags = ifp->if_flags;
ifp->if_ioctl = SIP_DECL(ioctl);
ifp->if_start = SIP_DECL(start);
ifp->if_watchdog = SIP_DECL(watchdog);
@ -1551,7 +1554,22 @@ SIP_DECL(ioctl)(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
break;
case SIOCSIFFLAGS:
/* If the interface is up and running, only modify the receive
* filter when setting promiscuous or debug mode. Otherwise
* fall through to ether_ioctl, which will reset the chip.
*/
#define RESETIGN (IFF_CANTCHANGE|IFF_DEBUG)
if (((ifp->if_flags & (IFF_UP|IFF_RUNNING))
== (IFF_UP|IFF_RUNNING))
&& ((ifp->if_flags & (~RESETIGN))
== (sc->sc_if_flags & (~RESETIGN)))) {
/* Set up the receive filter. */
(*sc->sc_model->sip_variant->sipv_set_filter)(sc);
break;
#undef RESETIGN
}
/* FALLTHROUGH */
default:
error = ether_ioctl(ifp, cmd, data);
if (error == ENETRESET) {
@ -1569,6 +1587,7 @@ SIP_DECL(ioctl)(struct ifnet *ifp, u_long cmd, caddr_t data)
/* Try to get more packets going. */
SIP_DECL(start)(ifp);
sc->sc_if_flags = ifp->if_flags;
splx(s);
return (error);
}
@ -2542,6 +2561,7 @@ SIP_DECL(init)(struct ifnet *ifp)
*/
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
sc->sc_if_flags = ifp->if_flags;
out:
if (error)