diff --git a/sys/dev/rge/if_rge.c b/sys/dev/rge/if_rge.c --- a/sys/dev/rge/if_rge.c +++ b/sys/dev/rge/if_rge.c @@ -959,29 +959,24 @@ case SIOCSIFFLAGS: RGE_LOCK(sc); if ((if_getflags(ifp) & IFF_UP) != 0) { - if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) { - /* - * TODO: handle promisc/iffmulti changing - * without reprogramming everything. - */ + if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) { + if (((if_getflags(ifp) ^ sc->rge_if_flags) + & (IFF_PROMISC | IFF_ALLMULTI)) != 0) + rge_iff_locked(sc); + } else rge_init_locked(sc); - } else { - /* Reinit promisc/multi just in case */ - rge_iff_locked(sc); - } } else { - if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) { + if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) rge_stop_locked(sc); - } } + sc->rge_if_flags = if_getflags(ifp); RGE_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: RGE_LOCK(sc); - if ((if_getflags(ifp) & IFF_DRV_RUNNING) != 0) { + if ((if_getflags(ifp) & IFF_DRV_RUNNING) != 0) rge_iff_locked(sc); - } RGE_UNLOCK(sc); break; case SIOCGIFMEDIA: diff --git a/sys/dev/rge/if_rgevar.h b/sys/dev/rge/if_rgevar.h --- a/sys/dev/rge/if_rgevar.h +++ b/sys/dev/rge/if_rgevar.h @@ -200,6 +200,8 @@ #define RGE_IMTYPE_SIM 1 int sc_watchdog; + int rge_if_flags; + uint32_t sc_debug; struct rge_drv_stats sc_drv_stats;