Use ether_set_ifflags_cb()

This commit is contained in:
msaitoh 2010-07-21 15:35:39 +00:00
parent d36c53b8ff
commit 5793a7f911
2 changed files with 53 additions and 66 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_bge.c,v 1.185 2010/06/03 00:05:36 msaitoh Exp $ */
/* $NetBSD: if_bge.c,v 1.186 2010/07/21 15:35:39 msaitoh Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
@ -79,7 +79,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.185 2010/06/03 00:05:36 msaitoh Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.186 2010/07/21 15:35:39 msaitoh Exp $");
#include "vlan.h"
#include "rnd.h"
@ -208,6 +208,7 @@ static int bge_encap(struct bge_softc *, struct mbuf *, uint32_t *);
static int bge_intr(void *);
static void bge_start(struct ifnet *);
static int bge_ifflags_cb(struct ethercom *);
static int bge_ioctl(struct ifnet *, u_long, void *);
static int bge_init(struct ifnet *);
static void bge_stop(struct ifnet *, int);
@ -3014,6 +3015,7 @@ bge_attach(device_t parent, device_t self, void *aux)
if_attach(ifp);
DPRINTFN(5, ("ether_ifattach\n"));
ether_ifattach(ifp, eaddr);
ether_set_ifflags_cb(&sc->ethercom, bge_ifflags_cb);
#if NRND > 0
rnd_attach_source(&sc->rnd_source, device_xname(sc->bge_dev),
RND_TYPE_NET, 0);
@ -4371,6 +4373,7 @@ bge_init(struct ifnet *ifp)
callout_reset(&sc->bge_timeout, hz, bge_tick, sc);
out:
sc->bge_if_flags = ifp->if_flags;
splx(s);
return error;
@ -4480,6 +4483,29 @@ bge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
sc->bge_flowflags;
}
static int
bge_ifflags_cb(struct ethercom *ec)
{
struct ifnet *ifp = &ec->ec_if;
struct bge_softc *sc = ifp->if_softc;
int change = ifp->if_flags ^ sc->bge_if_flags;
if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0)
return ENETRESET;
else if ((change & (IFF_PROMISC | IFF_ALLMULTI)) == 0)
return 0;
if ((ifp->if_flags & IFF_PROMISC) == 0)
BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
else
BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
bge_setmulti(sc);
sc->bge_if_flags = ifp->if_flags;
return 0;
}
static int
bge_ioctl(struct ifnet *ifp, u_long command, void *data)
{
@ -4491,37 +4517,6 @@ bge_ioctl(struct ifnet *ifp, u_long command, void *data)
s = splnet();
switch (command) {
case SIOCSIFFLAGS:
if ((error = ifioctl_common(ifp, command, data)) != 0)
break;
if (ifp->if_flags & IFF_UP) {
/*
* If only the state of the PROMISC flag changed,
* then just use the 'set promisc mode' command
* instead of reinitializing the entire NIC. Doing
* a full re-init means reloading the firmware and
* waiting for it to start up, which may take a
* second or two.
*/
if (ifp->if_flags & IFF_RUNNING &&
ifp->if_flags & IFF_PROMISC &&
!(sc->bge_if_flags & IFF_PROMISC)) {
BGE_SETBIT(sc, BGE_RX_MODE,
BGE_RXMODE_RX_PROMISC);
} else if (ifp->if_flags & IFF_RUNNING &&
!(ifp->if_flags & IFF_PROMISC) &&
sc->bge_if_flags & IFF_PROMISC) {
BGE_CLRBIT(sc, BGE_RX_MODE,
BGE_RXMODE_RX_PROMISC);
} else if (!(sc->bge_if_flags & IFF_UP))
bge_init(ifp);
} else {
if (ifp->if_flags & IFF_RUNNING)
bge_stop(ifp, 1);
}
sc->bge_if_flags = ifp->if_flags;
error = 0;
break;
case SIOCSIFMEDIA:
/* XXX Flow control is not supported for 1000BASE-SX */
if (sc->bge_flags & BGE_PHY_FIBER_TBI) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.212 2010/07/19 15:46:37 jakllsch Exp $ */
/* $NetBSD: if_wm.c,v 1.213 2010/07/21 15:35:39 msaitoh Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.212 2010/07/19 15:46:37 jakllsch Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.213 2010/07/21 15:35:39 msaitoh Exp $");
#include "rnd.h"
@ -499,6 +499,7 @@ do { \
static void wm_start(struct ifnet *);
static void wm_watchdog(struct ifnet *);
static int wm_ifflags_cb(struct ethercom *);
static int wm_ioctl(struct ifnet *, u_long, void *);
static int wm_init(struct ifnet *);
static void wm_stop(struct ifnet *, int);
@ -1925,6 +1926,7 @@ wm_attach(device_t parent, device_t self, void *aux)
*/
if_attach(ifp);
ether_ifattach(ifp, enaddr);
ether_set_ifflags_cb(&sc->sc_ethercom, wm_ifflags_cb);
#if NRND > 0
rnd_attach_source(&sc->rnd_source, xname, RND_TYPE_NET, 0);
#endif
@ -2729,6 +2731,24 @@ wm_watchdog(struct ifnet *ifp)
wm_start(ifp);
}
static int
wm_ifflags_cb(struct ethercom *ec)
{
struct ifnet *ifp = &ec->ec_if;
struct wm_softc *sc = ifp->if_softc;
int change = ifp->if_flags ^ sc->sc_if_flags;
if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0)
return ENETRESET;
else if ((change & (IFF_PROMISC | IFF_ALLMULTI)) == 0)
return 0;
wm_set_filter(sc);
sc->sc_if_flags = ifp->if_flags;
return 0;
}
/*
* wm_ioctl: [ifnet interface function]
*
@ -2741,40 +2761,11 @@ wm_ioctl(struct ifnet *ifp, u_long cmd, void *data)
struct ifreq *ifr = (struct ifreq *) data;
struct ifaddr *ifa = (struct ifaddr *)data;
struct sockaddr_dl *sdl;
int diff, s, error;
int s, error;
s = splnet();
switch (cmd) {
case SIOCSIFFLAGS:
if ((error = ifioctl_common(ifp, cmd, data)) != 0)
break;
if (ifp->if_flags & IFF_UP) {
diff = (ifp->if_flags ^ sc->sc_if_flags)
& (IFF_PROMISC | IFF_ALLMULTI);
if ((diff & (IFF_PROMISC | IFF_ALLMULTI)) != 0) {
/*
* If the difference bettween last flag and
* new flag is only IFF_PROMISC or
* IFF_ALLMULTI, set multicast filter only
* (don't reset to prevent link down).
*/
wm_set_filter(sc);
} else {
/*
* Reset the interface to pick up changes in
* any other flags that affect the hardware
* state.
*/
wm_init(ifp);
}
} else {
if (ifp->if_flags & IFF_RUNNING)
wm_stop(ifp, 1);
}
sc->sc_if_flags = ifp->if_flags;
error = 0;
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
/* Flow control requires full-duplex mode. */
@ -3936,7 +3927,7 @@ wm_init(struct ifnet *ifp)
else
sc->sc_ctrl &= ~CTRL_VME;
/* Write the control registers. */
/* Write the control register. */
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
if (sc->sc_flags & WM_F_HAS_MII) {
@ -4138,6 +4129,7 @@ wm_init(struct ifnet *ifp)
ifp->if_flags &= ~IFF_OACTIVE;
out:
sc->sc_if_flags = ifp->if_flags;
if (error)
log(LOG_ERR, "%s: interface not running\n",
device_xname(sc->sc_dev));