diff --git a/sys/dev/etherswitch/felix/felix.c b/sys/dev/etherswitch/felix/felix.c index f57a6e1daa0..a80f4f8d15a 100644 --- a/sys/dev/etherswitch/felix/felix.c +++ b/sys/dev/etherswitch/felix/felix.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -325,6 +326,33 @@ felix_setup(felix_softc_t sc) return (0); } +static int +felix_timer_rate(SYSCTL_HANDLER_ARGS) +{ + felix_softc_t sc; + int error, value, old; + + sc = arg1; + + old = value = sc->timer_ticks; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + + if (value < 0) + return (EINVAL); + + if (value == old) + return (0); + + FELIX_LOCK(sc); + sc->timer_ticks = value; + callout_reset(&sc->tick_callout, sc->timer_ticks, felix_tick, sc); + FELIX_UNLOCK(sc); + + return (0); +} + static int felix_attach(device_t dev) { @@ -426,6 +454,13 @@ felix_attach(device_t dev) if (error != 0) goto out_fail; + sc->timer_ticks = hz; /* Default to 1s. */ + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "timer_ticks", CTLTYPE_INT | CTLFLAG_RW, + sc, 0, felix_timer_rate, "I", + "Number of ticks between timer invocations"); + /* The tick routine has to be called with the lock held. */ FELIX_LOCK(sc); felix_tick(sc); @@ -922,7 +957,8 @@ felix_tick(void *arg) MPASS(mii != NULL); mii_tick(mii); } - callout_reset(&sc->tick_callout, hz, felix_tick, sc); + if (sc->timer_ticks != 0) + callout_reset(&sc->tick_callout, sc->timer_ticks, felix_tick, sc); } static int diff --git a/sys/dev/etherswitch/felix/felix_var.h b/sys/dev/etherswitch/felix/felix_var.h index d891419793b..15f43ec6a3d 100644 --- a/sys/dev/etherswitch/felix/felix_var.h +++ b/sys/dev/etherswitch/felix/felix_var.h @@ -102,6 +102,8 @@ typedef struct felix_softc { int vlan_mode; int vlans[FELIX_NUM_VLANS]; + + uint32_t timer_ticks; } *felix_softc_t; #endif