git: d88aecce69c8 - main - felix: Add a sysctl to control timer routine frequency

From: Wojciech Macek <wma_at_FreeBSD.org>
Date: Fri, 29 Oct 2021 08:31:43 UTC
The branch main has been updated by wma:

URL: https://cgit.FreeBSD.org/src/commit/?id=d88aecce69c82e9312c4e5e4e9eab4c56284925f

commit d88aecce69c82e9312c4e5e4e9eab4c56284925f
Author:     Kornel Duleba <mindal@semihalf.com>
AuthorDate: 2021-10-25 13:18:27 +0000
Commit:     Wojciech Macek <wma@FreeBSD.org>
CommitDate: 2021-10-29 08:08:26 +0000

    felix: Add a sysctl to control timer routine frequency
    
    Driver polls status of all PHYs connected to the switch in a
    fixed interval.
    Add a sysctl that allows to control frequency of that.
    The value is expressed in ticks and defaults to "hz", or 1 second.
    
    Obtained from: Semihalf
    Sponsored by: Alstom Group
---
 sys/dev/etherswitch/felix/felix.c     | 38 ++++++++++++++++++++++++++++++++++-
 sys/dev/etherswitch/felix/felix_var.h |  2 ++
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/sys/dev/etherswitch/felix/felix.c b/sys/dev/etherswitch/felix/felix.c
index f57a6e1daa0c..a80f4f8d15ae 100644
--- a/sys/dev/etherswitch/felix/felix.c
+++ b/sys/dev/etherswitch/felix/felix.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
+#include <sys/sysctl.h>
 #include <sys/rman.h>
 
 #include <machine/bus.h>
@@ -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 d891419793b7..15f43ec6a3d2 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