Index | Thread | Search

From:
Janne Johansson <icepic.dz@gmail.com>
Subject:
Re: SoftLRO diff for cnmac/octeon
To:
Jan Klemkow <j.klemkow@wemelug.de>
Cc:
tech@openbsd.org, visa@openbsd.org
Date:
Wed, 4 Feb 2026 11:04:22 +0100

Download raw body.

Thread
> The following macro is needed, or your diff breaks SMALL_KERNELs like
> the bsd.rd.
>
> #ifndef SMALL_KERNEL
>
> > -     ml_enqueue(ml, m);
> > +     if (ISSET(ifp->if_xflags, IFXF_LRO))
>
> It there a way do differentiate between TCP and over packets?
> So, you could use the same pattern, as in the other drivers?
> Is there a programmers guide for this chip, which might help?

Tried looking at the NDK fbsd 11 has in their sys/contrib and some
linux cavium sources, but since its all named differently, it is very
had to discern if there is a simple way to notice those.
Also tested on ERL3 now, bumps tcp receive from 100-ish Mbit to 400Mbit/s.

The SMALL_KERNEL diff is at

https://s3.sto3.safedc.net/jj-public-files/small-kernel-cnmac-softlro.diff

Since it was softlro that pulls in the netinet/tcp* headers, I put
that behind ifndef SMALL_KERNEL too, no need to pull them in if not
gluing packets.

Index: if_cnmac.c
===================================================================
RCS file: /cvs/src/sys/arch/octeon/dev/if_cnmac.c,v
diff -u -p -u -r1.86 if_cnmac.c
--- if_cnmac.c  20 May 2024 23:13:33 -0000      1.86
+++ if_cnmac.c  4 Feb 2026 08:55:25 -0000
@@ -55,6 +55,11 @@
 #include <net/if_media.h>
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
+#ifndef SMALL_KERNEL
+#include <netinet/tcp.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+#endif /* SMALL_KERNEL */

 #if NBPFILTER > 0
 #include <net/bpf.h>
@@ -306,7 +311,7 @@ cnmac_attach(struct device *parent, stru
        strncpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof(ifp->if_xname));
        ifp->if_softc = sc;
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-       ifp->if_xflags = IFXF_MPSAFE;
+       ifp->if_xflags = IFXF_MPSAFE|IFXF_LRO;
        ifp->if_ioctl = cnmac_ioctl;
        ifp->if_qstart = cnmac_start;
        ifp->if_watchdog = cnmac_watchdog;
@@ -314,7 +319,8 @@ cnmac_attach(struct device *parent, stru
        ifq_init_maxlen(&ifp->if_snd, max(GATHER_QUEUE_SIZE, IFQ_MAXLEN));

        ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_CSUM_TCPv4 |
-           IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6;
+           IFCAP_CSUM_UDPv4 | IFCAP_CSUM_TCPv6 | IFCAP_CSUM_UDPv6 |
+           IFCAP_LRO;

        cn30xxgmx_set_filter(sc->sc_gmx_port);

@@ -1246,7 +1252,13 @@ cnmac_recv(struct cnmac_softc *sc, uint6
                            M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK;
        }

-       ml_enqueue(ml, m);
+#ifndef SMALL_KERNEL
+       if (__predict_true(ISSET(ifp->if_xflags, IFXF_LRO)))
+         tcp_softlro_glue(ml, m, ifp);
+       else
+#else
+        ml_enqueue(ml, m);
+#endif

        return nmbuf;


-- 
May the most significant bit of your life be positive.