You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2026/01/19 15:22:52 UTC

(nuttx) branch master updated (9903b116562 -> b01f8b04e97)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 9903b116562 drivers/rpmsg: remove unnecessary header files, revise make.def and cmake
     new d2dde8a29a8 net/netdev: modify for hardware checksum offload
     new 42da4e322aa net/netdev: fix compile error and add cmake/makefile
     new 99bf7c3c5f6 net: skip TCP/UDP pseudo-header checksum with hardware offload
     new b01f8b04e97 netdev: delete macro CONFIG_NETDEV_CHECKSUM with nuttx

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Documentation/components/net/netdev.rst |  29 ++++
 include/nuttx/net/netdev.h              | 146 ++++++++----------
 net/devif/ipv4_input.c                  |   3 +-
 net/inet/ipv4_build_header.c            |   1 +
 net/netdev/CMakeLists.txt               |   2 +
 net/netdev/Make.defs                    |   2 +
 net/netdev/netdev.h                     |  93 +++++++++++
 net/netdev/netdev_checksum.c            | 264 ++++++++++++++++++++++++++++++++
 net/tcp/tcp_input.c                     |   3 +-
 net/tcp/tcp_send.c                      |  20 ++-
 net/udp/udp_input.c                     |   8 +-
 net/udp/udp_send.c                      |  25 +--
 12 files changed, 491 insertions(+), 105 deletions(-)
 create mode 100644 net/netdev/netdev_checksum.c


(nuttx) 01/04: net/netdev: modify for hardware checksum offload

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d2dde8a29a8875fca06c67054a3a228683d73904
Author: daichuan <da...@xiaomi.com>
AuthorDate: Sat Aug 30 01:17:47 2025 +0800

    net/netdev: modify for hardware checksum offload
    
    Implementation of main hardware verification and uninstallation functions
    
    Signed-off-by: daichuan <da...@xiaomi.com>
---
 include/nuttx/net/netdev.h   |   9 ++
 net/devif/ipv4_input.c       |   3 +-
 net/inet/ipv4_build_header.c |   1 +
 net/netdev/Kconfig           |   9 ++
 net/netdev/netdev_checksum.c | 195 +++++++++++++++++++++++++++++++++++++++++++
 net/tcp/tcp_input.c          |   3 +-
 net/tcp/tcp_send.c           |  46 +++++++++-
 net/udp/udp_input.c          |   8 +-
 net/udp/udp_send.c           |  23 ++++-
 9 files changed, 287 insertions(+), 10 deletions(-)

diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h
index deccb9a6563..cfb9c84f901 100644
--- a/include/nuttx/net/netdev.h
+++ b/include/nuttx/net/netdev.h
@@ -80,6 +80,11 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* Hardware features bits */
+
+#define NETDEV_TX_CSUM  (1 << 1) /* Netdev support hardware tx checksum */
+#define NETDEV_RX_CSUM  (1 << 2) /* Netdev support hardware rx checksum */
+
 /* Determine the largest possible address */
 
 #if defined(CONFIG_WIRELESS_IEEE802154) && defined(CONFIG_WIRELESS_PKTRADIO)
@@ -341,6 +346,10 @@ struct net_driver_s
 
   uint32_t d_flags;
 
+  /* Hardware features. See NETDEV_* definitions */
+
+  uint8_t d_features;
+
   /* Multi network devices using multiple link layer protocols are
    * supported
    */
diff --git a/net/devif/ipv4_input.c b/net/devif/ipv4_input.c
index 7fbf8d003be..7b8537bcd00 100644
--- a/net/devif/ipv4_input.c
+++ b/net/devif/ipv4_input.c
@@ -447,7 +447,8 @@ static int ipv4_in(FAR struct net_driver_s *dev)
 #endif
 
 #ifdef CONFIG_NET_IPV4_CHECKSUMS
-  if (ipv4_chksum(IPv4BUF) != 0xffff)
+  if (((dev->d_features & NETDEV_RX_CSUM) == 0)
+      && (ipv4_chksum(IPv4BUF) != 0xffff))
     {
       /* Compute and check the IP header checksum. */
 
diff --git a/net/inet/ipv4_build_header.c b/net/inet/ipv4_build_header.c
index be697258ff7..4849d7bff88 100644
--- a/net/inet/ipv4_build_header.c
+++ b/net/inet/ipv4_build_header.c
@@ -59,6 +59,7 @@ static uint16_t g_ipid;
  *   src_ip     Source IPv4 address
  *   dst_ip     Destination IPv4 address
  *   ttl        Time to live(IPv4)
+ *   tos        Type of Service(IPv4)
  *   opt        IPv4 options
  *
  * Returned Value:
diff --git a/net/netdev/Kconfig b/net/netdev/Kconfig
index 227b5c2d58f..9e293e15747 100644
--- a/net/netdev/Kconfig
+++ b/net/netdev/Kconfig
@@ -99,4 +99,13 @@ config NETDOWN_NOTIFIER
 		notifier, but was developed specifically to support SIGHUP poll()
 		logic.
 
+config NETDEV_CHECKSUM
+	bool "netdev hardware checksum"
+	default n
+	---help---
+		To support hardware checksum calculation for network cards, we
+		need to know the starting position of the L4 layer header in
+		the iob buffer, as well as the offset of the checksum field
+		within the L4 layer.
+
 endmenu # Network Device Operations
diff --git a/net/netdev/netdev_checksum.c b/net/netdev/netdev_checksum.c
new file mode 100644
index 00000000000..b8bf44e0c83
--- /dev/null
+++ b/net/netdev/netdev_checksum.c
@@ -0,0 +1,195 @@
+/****************************************************************************
+ * net/netdev/netdev_checksum.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/net/netdev.h>
+
+#include "netdev/netdev.h"
+
+#ifdef CONFIG_NETDEV_CHECKSUM
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hardware_chksum_start
+ *
+ * Description:
+ *   get checksum start offset position with iob buffer
+ *
+ * Input Parameters:
+ *   dev       -  The driver structure
+ *   iphdrlen  -  ipv4/ipv6 header length
+ *
+ * Returned Value:
+ *   The checksum start offset position
+ *
+ ****************************************************************************/
+
+static int32_t hardware_chksum_start(FAR struct iob_s *iob,
+                                     uint16_t iphdrlen)
+{
+  int32_t start = 0;
+
+  if (iphdrlen > iob->io_len)
+    {
+      return -EINVAL;
+    }
+
+  if (iob != NULL)
+    {
+      start = iob->io_offset + iphdrlen;
+    }
+
+  return start;
+}
+
+/****************************************************************************
+ * Name: hardware_chksum_get_proto
+ *
+ * Description:
+ *   get proto with dev.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The proto value
+ *
+ ****************************************************************************/
+
+static uint8_t hardware_chksum_get_proto(FAR struct net_driver_s *dev)
+{
+  uint8_t proto;
+
+  if (IFF_IS_IPv6(dev->d_flags))
+    {
+      FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
+      proto = ipv6->proto;
+    }
+  else
+    {
+      FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
+      proto = ipv4->proto;
+    }
+
+  return proto;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: netdev_checksum_start
+ *
+ * Description:
+ *   get checksum start offset position with iob, then hardwear can
+ *   use to calculate the package payload checksum value.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The checksum start offset position, -EINVAL is mean not need calculate
+ *   with hardware
+ *
+ ****************************************************************************/
+
+int netdev_checksum_start(FAR struct net_driver_s *dev)
+{
+  int start;
+
+  if (IFF_IS_IPv6(dev->d_flags))
+    {
+      FAR struct ipv6_hdr_s *ipv6 =
+        (FAR struct ipv6_hdr_s *)(IOB_DATA(dev->d_iob));
+
+      if ((ipv6->proto == IP_PROTO_UDP) || (ipv6->proto == IP_PROTO_TCP))
+        {
+          start = hardware_chksum_start(dev->d_iob, IPv6_HDRLEN);
+        }
+      else
+        {
+          return -EINVAL;
+        }
+    }
+  else
+    {
+      FAR struct ipv4_hdr_s *ipv4 =
+        (FAR struct ipv4_hdr_s *)(IOB_DATA(dev->d_iob));
+
+      if ((ipv4->proto == IP_PROTO_UDP) || (ipv4->proto == IP_PROTO_TCP))
+        {
+          start = hardware_chksum_start(dev->d_iob,
+                                        ((ipv4->vhl & IPv4_HLMASK) << 2));
+        }
+      else
+        {
+          return -EINVAL;
+        }
+    }
+
+  return start;
+}
+
+/****************************************************************************
+ * Name: netdev_checksum_offset
+ *
+ * Description:
+ *   get checksum field offset with tcp/udp header.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The checksum field offset with L4, -EINVAL is mean not need calculate
+ *   with hardware
+ *
+ ****************************************************************************/
+
+int netdev_checksum_offset(FAR struct net_driver_s *dev)
+{
+  int offset = 0;
+  uint8_t proto = hardware_chksum_get_proto(dev);
+
+  if (proto == IP_PROTO_UDP)
+    {
+      offset = offsetof(struct udp_hdr_s, udpchksum);
+    }
+  else if (proto == IP_PROTO_TCP)
+    {
+      offset = offsetof(struct tcp_hdr_s, tcpchksum);
+    }
+  else
+    {
+      return -EINVAL;
+    }
+
+  return offset;
+}
+
+#endif /* CONFIG_NETDEV_CHECKSUM */
diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c
index 54cbd2e73d8..003665cfa1c 100644
--- a/net/tcp/tcp_input.c
+++ b/net/tcp/tcp_input.c
@@ -726,7 +726,8 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
 #ifdef CONFIG_NET_TCP_CHECKSUMS
   /* Start of TCP input header processing code. */
 
-  if (tcp_chksum(dev) != 0xffff)
+  if (((dev->d_features & NETDEV_RX_CSUM) == 0)
+      && (tcp_chksum(dev) != 0xffff))
     {
       /* Compute and check the TCP checksum. */
 
diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c
index 5713d2d7eed..574691e935e 100644
--- a/net/tcp/tcp_send.c
+++ b/net/tcp/tcp_send.c
@@ -200,7 +200,17 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
       tcp->tcpchksum = 0;
 
 #ifdef CONFIG_NET_TCP_CHECKSUMS
-      tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
+      if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+        {
+          tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
+        }
+      else
+        {
+          uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
+                                                          IP_PROTO_TCP,
+                                                          IPv6_HDRLEN);
+          tcp->tcpchksum = HTONS(chksum);
+        }
 #endif
 
 #ifdef CONFIG_NET_STATISTICS
@@ -224,7 +234,16 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
       tcp->tcpchksum = 0;
 
 #ifdef CONFIG_NET_TCP_CHECKSUMS
-      tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
+      if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+        {
+          tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
+        }
+      else
+        {
+          uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
+                                                          IP_PROTO_TCP);
+          tcp->tcpchksum = HTONS(chksum);
+        }
 #endif
 
 #ifdef CONFIG_NET_STATISTICS
@@ -507,7 +526,17 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
       tcp->tcpchksum = 0;
 
 #ifdef CONFIG_NET_TCP_CHECKSUMS
-      tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
+      if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+        {
+          tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
+        }
+      else
+        {
+          uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
+                                                          IP_PROTO_TCP,
+                                                          IPv6_HDRLEN);
+          tcp->tcpchksum = HTONS(chksum);
+        }
 #endif
     }
 #endif /* CONFIG_NET_IPv6 */
@@ -527,7 +556,16 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
       tcp->tcpchksum = 0;
 
 #ifdef CONFIG_NET_TCP_CHECKSUMS
-      tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
+      if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+        {
+          tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
+        }
+      else
+        {
+          uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
+                                                          IP_PROTO_TCP);
+          tcp->tcpchksum = HTONS(chksum);
+        }
 #endif
     }
 #endif /* CONFIG_NET_IPv4 */
diff --git a/net/udp/udp_input.c b/net/udp/udp_input.c
index 15534e37b97..1ad1724a54e 100644
--- a/net/udp/udp_input.c
+++ b/net/udp/udp_input.c
@@ -217,7 +217,7 @@ static int udp_input(FAR struct net_driver_s *dev, unsigned int iplen)
   unsigned int udpiplen;
   unsigned int udpdatalen = dev->d_len - iplen;
 #ifdef CONFIG_NET_UDP_CHECKSUMS
-  uint16_t chksum;
+  uint16_t chksum = 0;
 #endif
   int ret = OK;
 
@@ -256,7 +256,11 @@ static int udp_input(FAR struct net_driver_s *dev, unsigned int iplen)
   dev->d_appdata = IPBUF(udpiplen);
 
 #ifdef CONFIG_NET_UDP_CHECKSUMS
-  chksum = udp->udpchksum;
+  if ((dev->d_features & NETDEV_RX_CSUM) == 0)
+    {
+      chksum = udp->udpchksum;
+    }
+
   if (chksum != 0)
     {
 #ifdef CONFIG_NET_IPv6
diff --git a/net/udp/udp_send.c b/net/udp/udp_send.c
index 8b59be7fb2f..aaa1c5a09df 100644
--- a/net/udp/udp_send.c
+++ b/net/udp/udp_send.c
@@ -255,7 +255,16 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
       if (IFF_IS_IPv4(dev->d_flags))
 #endif
         {
-          udp->udpchksum = ~udp_ipv4_chksum(dev);
+          if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+            {
+              udp->udpchksum = ~udp_ipv4_chksum(dev);
+            }
+          else
+            {
+              uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
+                                                              IP_PROTO_UDP);
+              udp->udpchksum = HTONS(chksum);
+            }
         }
 #endif /* CONFIG_NET_IPv4 */
 
@@ -264,7 +273,17 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
       else
 #endif
         {
-          udp->udpchksum = ~udp_ipv6_chksum(dev);
+          if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+            {
+              udp->udpchksum = ~udp_ipv6_chksum(dev);
+            }
+          else
+            {
+              uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
+                                                              IP_PROTO_UDP,
+                                                              IPv6_HDRLEN);
+              udp->udpchksum = HTONS(chksum);
+            }
         }
 #endif /* CONFIG_NET_IPv6 */
 


(nuttx) 02/04: net/netdev: fix compile error and add cmake/makefile

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 42da4e322aab07bfef1002798e68b26e4c0c82f2
Author: daichuan <da...@xiaomi.com>
AuthorDate: Sat Aug 30 01:18:03 2025 +0800

    net/netdev: fix compile error and add cmake/makefile
    
    Fix compilation errors and add build files
    
    Signed-off-by: daichuan <da...@xiaomi.com>
---
 net/netdev/CMakeLists.txt    | 4 ++++
 net/netdev/Make.defs         | 4 ++++
 net/netdev/netdev_checksum.c | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/net/netdev/CMakeLists.txt b/net/netdev/CMakeLists.txt
index ac4e60ebf17..1149a44d651 100644
--- a/net/netdev/CMakeLists.txt
+++ b/net/netdev/CMakeLists.txt
@@ -57,4 +57,8 @@ if(CONFIG_NETDEV_RSS)
   list(APPEND SRCS netdev_notify_recvcpu.c)
 endif()
 
+if(CONFIG_NETDEV_CHECKSUM)
+  list(APPEND SRCS netdev_checksum.c)
+endif()
+
 target_sources(net PRIVATE ${SRCS})
diff --git a/net/netdev/Make.defs b/net/netdev/Make.defs
index 14bbe04fe97..81551344a42 100644
--- a/net/netdev/Make.defs
+++ b/net/netdev/Make.defs
@@ -48,6 +48,10 @@ ifeq ($(CONFIG_NETDEV_RSS),y)
 NETDEV_CSRCS += netdev_notify_recvcpu.c
 endif
 
+ifeq ($(CONFIG_NETDEV_CHECKSUM),y)
+NETDEV_CSRCS += netdev_checksum.c
+endif
+
 # Include netdev build support
 
 DEPPATH += --dep-path netdev
diff --git a/net/netdev/netdev_checksum.c b/net/netdev/netdev_checksum.c
index b8bf44e0c83..24ad4ac9f8d 100644
--- a/net/netdev/netdev_checksum.c
+++ b/net/netdev/netdev_checksum.c
@@ -25,6 +25,8 @@
  ****************************************************************************/
 
 #include <nuttx/net/netdev.h>
+#include <nuttx/net/udp.h>
+#include <nuttx/net/tcp.h>
 
 #include "netdev/netdev.h"
 


(nuttx) 04/04: netdev: delete macro CONFIG_NETDEV_CHECKSUM with nuttx

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit b01f8b04e97893d61b17b6aa13909fc1fbc1709f
Author: daichuan <da...@xiaomi.com>
AuthorDate: Mon Jan 19 14:29:59 2026 +0800

    netdev: delete macro CONFIG_NETDEV_CHECKSUM with nuttx
    
    not need CONFIG_NETDEV_CHECKSUM with nuttx
    
    Signed-off-by: daichuan <da...@xiaomi.com>
---
 Documentation/components/net/netdev.rst | 17 +++------
 arch/Kconfig                            |  4 ---
 include/nuttx/net/netdev.h              |  6 ----
 net/netdev/CMakeLists.txt               |  4 +--
 net/netdev/Kconfig                      | 10 ------
 net/netdev/Make.defs                    |  2 --
 net/netdev/netdev_checksum.c            | 62 +++++++++++++++++++++++++--------
 7 files changed, 52 insertions(+), 53 deletions(-)

diff --git a/Documentation/components/net/netdev.rst b/Documentation/components/net/netdev.rst
index 47aaaac50c2..f63668c3276 100644
--- a/Documentation/components/net/netdev.rst
+++ b/Documentation/components/net/netdev.rst
@@ -180,17 +180,10 @@ The structure :c:struct:`net_driver_s` includes fields to support hardware
 checksum offloading. This feature allows the network stack to delegate
 checksum calculation to the network device hardware, improving performance.
 
-Checksum Configuration Options
-------------------------------
-
-* :c:macro:`CONFIG_NETDEV_CHECKSUM`: Enable support for hardware checksum
-  offloading in the network stack. This option requires the architecture
-  to support it (:c:macro:`ARCH_HAVE_NETDEV_CHECKSUM_HW`).
-
 Implementation Details
 ----------------------
 
-When :c:macro:`CONFIG_NETDEV_CHECKSUM` is enabled, the driver should use the
+Drivers that support hardware checksum offloading should use the
 following helper functions to retrieve checksum offload information:
 
 * :c:func:`netdev_checksum_start`: Get the offset from the beginning of the
@@ -202,11 +195,9 @@ following helper functions to retrieve checksum offload information:
 
 .. code-block:: c
 
-   #ifdef CONFIG_NETDEV_CHECKSUM
-     int netdev_checksum_start(FAR struct net_driver_s *dev);
-     int netdev_checksum_offset(FAR struct net_driver_s *dev);
-     uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev);
-   #endif
+   int netdev_checksum_start(FAR struct net_driver_s *dev);
+   int netdev_checksum_offset(FAR struct net_driver_s *dev);
+   uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev);
 
 Drivers that support hardware checksum offloading should use these functions
 to configure the hardware accordingly before transmitting the packet.
diff --git a/arch/Kconfig b/arch/Kconfig
index 17daa230344..7e3396308ad 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -575,10 +575,6 @@ config ARCH_HAVE_FETCHADD
 	bool
 	default n
 
-config ARCH_HAVE_NETDEV_CHECKSUM_HW
-	bool
-	default n
-
 config ARCH_HAVE_RTC_SUBSECONDS
 	bool
 	default n
diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h
index 34699a0c4e9..23a3f2f5e5d 100644
--- a/include/nuttx/net/netdev.h
+++ b/include/nuttx/net/netdev.h
@@ -1310,9 +1310,7 @@ void netdev_statistics_log(FAR void *arg);
  *
  ****************************************************************************/
 
-#ifdef CONFIG_NETDEV_CHECKSUM
 int netdev_checksum_start(FAR struct net_driver_s *dev);
-#endif
 
 /****************************************************************************
  * Name: netdev_checksum_offset
@@ -1329,9 +1327,7 @@ int netdev_checksum_start(FAR struct net_driver_s *dev);
  *
  ****************************************************************************/
 
-#ifdef CONFIG_NETDEV_CHECKSUM
 int netdev_checksum_offset(FAR struct net_driver_s *dev);
-#endif
 
 /****************************************************************************
  * Name: netdev_upperlayer_header_checksum
@@ -1347,8 +1343,6 @@ int netdev_checksum_offset(FAR struct net_driver_s *dev);
  *
  ****************************************************************************/
 
-#ifdef CONFIG_NETDEV_CHECKSUM
 uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev);
-#endif
 
 #endif /* __INCLUDE_NUTTX_NET_NETDEV_H */
diff --git a/net/netdev/CMakeLists.txt b/net/netdev/CMakeLists.txt
index 1149a44d651..09073152739 100644
--- a/net/netdev/CMakeLists.txt
+++ b/net/netdev/CMakeLists.txt
@@ -57,8 +57,6 @@ if(CONFIG_NETDEV_RSS)
   list(APPEND SRCS netdev_notify_recvcpu.c)
 endif()
 
-if(CONFIG_NETDEV_CHECKSUM)
-  list(APPEND SRCS netdev_checksum.c)
-endif()
+list(APPEND SRCS netdev_checksum.c)
 
 target_sources(net PRIVATE ${SRCS})
diff --git a/net/netdev/Kconfig b/net/netdev/Kconfig
index 2ef6287564c..227b5c2d58f 100644
--- a/net/netdev/Kconfig
+++ b/net/netdev/Kconfig
@@ -99,14 +99,4 @@ config NETDOWN_NOTIFIER
 		notifier, but was developed specifically to support SIGHUP poll()
 		logic.
 
-config NETDEV_CHECKSUM
-	bool "Enable support to netdev checksum in Hardware"
-	default n
-	depends on ARCH_HAVE_NETDEV_CHECKSUM_HW
-	---help---
-		To support hardware checksum calculation for network cards, we
-		need to know the starting position of the L4 layer header in
-		the iob buffer, as well as the offset of the checksum field
-		within the L4 layer.
-
 endmenu # Network Device Operations
diff --git a/net/netdev/Make.defs b/net/netdev/Make.defs
index 81551344a42..03611206814 100644
--- a/net/netdev/Make.defs
+++ b/net/netdev/Make.defs
@@ -48,9 +48,7 @@ ifeq ($(CONFIG_NETDEV_RSS),y)
 NETDEV_CSRCS += netdev_notify_recvcpu.c
 endif
 
-ifeq ($(CONFIG_NETDEV_CHECKSUM),y)
 NETDEV_CSRCS += netdev_checksum.c
-endif
 
 # Include netdev build support
 
diff --git a/net/netdev/netdev_checksum.c b/net/netdev/netdev_checksum.c
index d2c2cac7fe3..a2040976ba1 100644
--- a/net/netdev/netdev_checksum.c
+++ b/net/netdev/netdev_checksum.c
@@ -27,11 +27,10 @@
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/udp.h>
 #include <nuttx/net/tcp.h>
+#include <nuttx/mm/iob.h>
 
 #include "netdev/netdev.h"
 
-#ifdef CONFIG_NETDEV_CHECKSUM
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -51,6 +50,8 @@
  *
  ****************************************************************************/
 
+#if defined(CONFIG_MM_IOB) && \
+    (defined(CONFIG_NET_IPv4) || defined(CONFIG_NET_IPv6))
 static int32_t hardware_chksum_start(FAR struct iob_s *iob,
                                      uint16_t iphdrlen)
 {
@@ -68,6 +69,7 @@ static int32_t hardware_chksum_start(FAR struct iob_s *iob,
 
   return start;
 }
+#endif
 
 /****************************************************************************
  * Name: hardware_chksum_get_proto
@@ -83,23 +85,33 @@ static int32_t hardware_chksum_start(FAR struct iob_s *iob,
  *
  ****************************************************************************/
 
+#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
 static uint8_t hardware_chksum_get_proto(FAR struct net_driver_s *dev)
 {
-  uint8_t proto;
+  uint8_t proto = 0;
 
+#ifdef CONFIG_NET_IPv6
+#  ifdef CONFIG_NET_IPv4
   if (IFF_IS_IPv6(dev->d_flags))
+#  endif
     {
       FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
       proto = ipv6->proto;
     }
+#endif
+#ifdef CONFIG_NET_IPv4
+#  ifdef CONFIG_NET_IPv6
   else
+#  endif
     {
       FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
       proto = ipv4->proto;
     }
+#endif
 
   return proto;
 }
+#endif
 
 /****************************************************************************
  * Public Functions
@@ -123,9 +135,13 @@ static uint8_t hardware_chksum_get_proto(FAR struct net_driver_s *dev)
 
 int netdev_checksum_start(FAR struct net_driver_s *dev)
 {
-  int start;
+#ifdef CONFIG_MM_IOB
+  int start = -EINVAL;
 
+#ifdef CONFIG_NET_IPv6
+#  ifdef CONFIG_NET_IPv4
   if (IFF_IS_IPv6(dev->d_flags))
+#  endif
     {
       FAR struct ipv6_hdr_s *ipv6 =
         (FAR struct ipv6_hdr_s *)(IOB_DATA(dev->d_iob));
@@ -139,7 +155,11 @@ int netdev_checksum_start(FAR struct net_driver_s *dev)
           return -EINVAL;
         }
     }
+#endif
+#ifdef CONFIG_NET_IPv4
+#  ifdef CONFIG_NET_IPv6
   else
+#  endif
     {
       FAR struct ipv4_hdr_s *ipv4 =
         (FAR struct ipv4_hdr_s *)(IOB_DATA(dev->d_iob));
@@ -154,8 +174,12 @@ int netdev_checksum_start(FAR struct net_driver_s *dev)
           return -EINVAL;
         }
     }
+#endif
 
   return start;
+#else
+  return -EINVAL;
+#endif
 }
 
 /****************************************************************************
@@ -175,23 +199,25 @@ int netdev_checksum_start(FAR struct net_driver_s *dev)
 
 int netdev_checksum_offset(FAR struct net_driver_s *dev)
 {
-  int offset = 0;
+#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_TCP)
   uint8_t proto = hardware_chksum_get_proto(dev);
+#endif
 
+#ifdef CONFIG_NET_UDP
   if (proto == IP_PROTO_UDP)
     {
-      offset = offsetof(struct udp_hdr_s, udpchksum);
-    }
-  else if (proto == IP_PROTO_TCP)
-    {
-      offset = offsetof(struct tcp_hdr_s, tcpchksum);
+      return offsetof(struct udp_hdr_s, udpchksum);
     }
-  else
+#endif
+
+#ifdef CONFIG_NET_TCP
+  if (proto == IP_PROTO_TCP)
     {
-      return -EINVAL;
+      return offsetof(struct tcp_hdr_s, tcpchksum);
     }
+#endif
 
-  return offset;
+  return -EINVAL;
 }
 
 /****************************************************************************
@@ -210,7 +236,10 @@ int netdev_checksum_offset(FAR struct net_driver_s *dev)
 
 uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev)
 {
+#ifdef CONFIG_NET_IPv6
+#  ifdef CONFIG_NET_IPv4
   if (IFF_IS_IPv6(dev->d_flags))
+#  endif
     {
       FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
 
@@ -218,15 +247,18 @@ uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev)
                                                  ipv6->proto,
                                                  IPv6_HDRLEN));
     }
+#endif
+#ifdef CONFIG_NET_IPv4
+#  ifdef CONFIG_NET_IPv6
   else
+#  endif
     {
       FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
 
       return HTONS(ipv4_upperlayer_header_chksum(dev,
                                                  ipv4->proto));
     }
+#endif
 
   return 0;
 }
-
-#endif /* CONFIG_NETDEV_CHECKSUM */


(nuttx) 03/04: net: skip TCP/UDP pseudo-header checksum with hardware offload

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 99bf7c3c5f657d991099646163d51d098ed1f5f2
Author: daichuan <da...@xiaomi.com>
AuthorDate: Sat Aug 30 01:18:20 2025 +0800

    net: skip TCP/UDP pseudo-header checksum with hardware offload
    
    When supporting hardware checksum offloading, the network protocol stack
    does not perform TCP/UDP pseudo-header checksum calculation.
    
    Skip TCP/UDP pseudo header checksum calculation in network protocol stack
    
    Signed-off-by: daichuan <da...@xiaomi.com>
---
 Documentation/components/net/netdev.rst |  38 +++++++++
 arch/Kconfig                            |   4 +
 include/nuttx/net/netdev.h              | 143 +++++++++++++-------------------
 net/netdev/Kconfig                      |   3 +-
 net/netdev/netdev.h                     |  93 +++++++++++++++++++++
 net/netdev/netdev_checksum.c            |  35 ++++++++
 net/tcp/tcp_send.c                      |  26 ------
 net/udp/udp_send.c                      |  32 ++-----
 8 files changed, 237 insertions(+), 137 deletions(-)

diff --git a/Documentation/components/net/netdev.rst b/Documentation/components/net/netdev.rst
index 1075ff9b30e..47aaaac50c2 100644
--- a/Documentation/components/net/netdev.rst
+++ b/Documentation/components/net/netdev.rst
@@ -173,6 +173,44 @@ Ioctls for IP Addresses
   to manage IPv6 addresses, by which you don't need to care about the
   slot it stored.
 
+Hardware Checksum Offload
+=========================
+
+The structure :c:struct:`net_driver_s` includes fields to support hardware
+checksum offloading. This feature allows the network stack to delegate
+checksum calculation to the network device hardware, improving performance.
+
+Checksum Configuration Options
+------------------------------
+
+* :c:macro:`CONFIG_NETDEV_CHECKSUM`: Enable support for hardware checksum
+  offloading in the network stack. This option requires the architecture
+  to support it (:c:macro:`ARCH_HAVE_NETDEV_CHECKSUM_HW`).
+
+Implementation Details
+----------------------
+
+When :c:macro:`CONFIG_NETDEV_CHECKSUM` is enabled, the driver should use the
+following helper functions to retrieve checksum offload information:
+
+* :c:func:`netdev_checksum_start`: Get the offset from the beginning of the
+  packet to the start of the L4 header (checksum calculation start).
+* :c:func:`netdev_checksum_offset`: Get the offset from the start of the L4
+  header to the checksum field.
+* :c:func:`netdev_upperlayer_header_checksum`: Calculate the pseudo-header
+  checksum.
+
+.. code-block:: c
+
+   #ifdef CONFIG_NETDEV_CHECKSUM
+     int netdev_checksum_start(FAR struct net_driver_s *dev);
+     int netdev_checksum_offset(FAR struct net_driver_s *dev);
+     uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev);
+   #endif
+
+Drivers that support hardware checksum offloading should use these functions
+to configure the hardware accordingly before transmitting the packet.
+
   [1]: https://man7.org/linux/man-pages/man7/netdevice.7.html
   [2]: e.g. 'eth0:0' stands for the secondary address on eth0
 
diff --git a/arch/Kconfig b/arch/Kconfig
index 7e3396308ad..17daa230344 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -575,6 +575,10 @@ config ARCH_HAVE_FETCHADD
 	bool
 	default n
 
+config ARCH_HAVE_NETDEV_CHECKSUM_HW
+	bool
+	default n
+
 config ARCH_HAVE_RTC_SUBSECONDS
 	bool
 	default n
diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h
index cfb9c84f901..34699a0c4e9 100644
--- a/include/nuttx/net/netdev.h
+++ b/include/nuttx/net/netdev.h
@@ -920,46 +920,6 @@ uint16_t net_chksum_iob(uint16_t sum, FAR struct iob_s *iob,
 
 #ifdef CONFIG_NET_IPv4
 
-/****************************************************************************
- * Name: ipv4_upperlayer_header_chksum
- *
- * Description:
- *   Perform the checksum calculation over the IPv4, protocol headers,
- *   IP source and destination addresses
- *
- * Input Parameters:
- *   dev   - The network driver instance. The packet data is in the d_buf
- *           of the device.
- *   proto - The protocol being supported
- *
- * Returned Value:
- *   The calculated checksum with pseudo-header and IP source and
- *   destination addresses
- *
- ****************************************************************************/
-
-uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev,
-                                       uint8_t proto);
-
-/****************************************************************************
- * Name: ipv4_upperlayer_payload_chksum
- *
- * Description:
- *   Perform the checksum calculation over the iob data payload
- *
- * Input Parameters:
- *   dev   - The network driver instance. The packet data is in the d_buf
- *           of the device.
- *   sum   - The default checksum
- *
- * Returned Value:
- *   The calculated checksum with iob data payload and default checksum
- *
- ****************************************************************************/
-
-uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
-                                        uint16_t sum);
-
 /****************************************************************************
  * Name: ipv4_upperlayer_chksum
  *
@@ -982,52 +942,6 @@ uint16_t ipv4_upperlayer_chksum(FAR struct net_driver_s *dev, uint8_t proto);
 
 #ifdef CONFIG_NET_IPv6
 
-/****************************************************************************
- * Name: ipv6_upperlayer_header_chksum
- *
- * Description:
- *   Perform the checksum calculation over the IPv6, protocol headers,
- *   IP source and destination addresses.
- *
- * Input Parameters:
- *   dev   - The network driver instance.  The packet data is in the d_buf
- *           of the device.
- *   proto - The protocol being supported
- *   iplen - The size of the IPv6 header.  This may be larger than
- *           IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
- *           present.
- *
- * Returned Value:
- *   The calculated checksum
- *
- ****************************************************************************/
-
-uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev,
-                                       uint8_t proto, unsigned int iplen);
-
-/****************************************************************************
- * Name: ipv6_upperlayer_payload_chksum
- *
- * Description:
- *   Perform the checksum calculation over the iob data payload and
- *   default checksum.
- *
- * Input Parameters:
- *   dev   - The network driver instance.  The packet data is in the d_buf
- *           of the device.
- *   proto - The protocol being supported
- *   iplen - The size of the IPv6 header.  This may be larger than
- *           IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
- *           present.
- *
- * Returned Value:
- *   The calculated checksum
- *
- ****************************************************************************/
-
-uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
-                                        unsigned int iplen, uint16_t sum);
-
 /****************************************************************************
  * Name: ipv6_upperlayer_chksum
  *
@@ -1380,4 +1294,61 @@ int netdev_ipv6_foreach(FAR struct net_driver_s *dev,
 void netdev_statistics_log(FAR void *arg);
 #endif
 
+/****************************************************************************
+ * Name: netdev_checksum_start
+ *
+ * Description:
+ *   Get checksum start offset position with iob, then hardware can
+ *   use to calculate the package payload checksum value.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The checksum start offset position, -EINVAL is mean not need calculate
+ *   with hardware
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_CHECKSUM
+int netdev_checksum_start(FAR struct net_driver_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: netdev_checksum_offset
+ *
+ * Description:
+ *   Get checksum field offset with tcp/udp header.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The checksum field offset with L4, -EINVAL is mean not need calculate
+ *   with hardware
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_CHECKSUM
+int netdev_checksum_offset(FAR struct net_driver_s *dev);
+#endif
+
+/****************************************************************************
+ * Name: netdev_upperlayer_header_checksum
+ *
+ * Description:
+ *   get upperlayer header checksum with tcp/udp header.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The upperlayer header checksum
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_CHECKSUM
+uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev);
+#endif
+
 #endif /* __INCLUDE_NUTTX_NET_NETDEV_H */
diff --git a/net/netdev/Kconfig b/net/netdev/Kconfig
index 9e293e15747..2ef6287564c 100644
--- a/net/netdev/Kconfig
+++ b/net/netdev/Kconfig
@@ -100,8 +100,9 @@ config NETDOWN_NOTIFIER
 		logic.
 
 config NETDEV_CHECKSUM
-	bool "netdev hardware checksum"
+	bool "Enable support to netdev checksum in Hardware"
 	default n
+	depends on ARCH_HAVE_NETDEV_CHECKSUM_HW
 	---help---
 		To support hardware checksum calculation for network cards, we
 		need to know the starting position of the L4 layer header in
diff --git a/net/netdev/netdev.h b/net/netdev/netdev.h
index 5f50d6dad4c..b5c24b0e770 100644
--- a/net/netdev/netdev.h
+++ b/net/netdev/netdev.h
@@ -503,6 +503,99 @@ void netdev_notify_recvcpu(FAR struct net_driver_s *dev,
                            FAR const void *dst_addr, uint16_t dst_port);
 #endif
 
+#ifdef CONFIG_NET_IPv4
+
+/****************************************************************************
+ * Name: ipv4_upperlayer_header_chksum
+ *
+ * Description:
+ *   Perform the checksum calculation over the IPv4, protocol headers,
+ *   IP source and destination addresses
+ *
+ * Input Parameters:
+ *   dev   - The network driver instance. The packet data is in the d_buf
+ *           of the device.
+ *   proto - The protocol being supported
+ *
+ * Returned Value:
+ *   The calculated checksum with pseudo-header and IP source and
+ *   destination addresses
+ *
+ ****************************************************************************/
+
+uint16_t ipv4_upperlayer_header_chksum(FAR struct net_driver_s *dev,
+                                       uint8_t proto);
+
+/****************************************************************************
+ * Name: ipv4_upperlayer_payload_chksum
+ *
+ * Description:
+ *   Perform the checksum calculation over the iob data payload
+ *
+ * Input Parameters:
+ *   dev   - The network driver instance. The packet data is in the d_buf
+ *           of the device.
+ *   sum   - The default checksum
+ *
+ * Returned Value:
+ *   The calculated checksum with iob data payload and default checksum
+ *
+ ****************************************************************************/
+
+uint16_t ipv4_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
+                                        uint16_t sum);
+#endif /* CONFIG_NET_IPv4 */
+
+#ifdef CONFIG_NET_IPv6
+
+/****************************************************************************
+ * Name: ipv6_upperlayer_header_chksum
+ *
+ * Description:
+ *   Perform the checksum calculation over the IPv6, protocol headers,
+ *   IP source and destination addresses.
+ *
+ * Input Parameters:
+ *   dev   - The network driver instance.  The packet data is in the d_buf
+ *           of the device.
+ *   proto - The protocol being supported
+ *   iplen - The size of the IPv6 header.  This may be larger than
+ *           IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
+ *           present.
+ *
+ * Returned Value:
+ *   The calculated checksum
+ *
+ ****************************************************************************/
+
+uint16_t ipv6_upperlayer_header_chksum(FAR struct net_driver_s *dev,
+                                       uint8_t proto, unsigned int iplen);
+
+/****************************************************************************
+ * Name: ipv6_upperlayer_payload_chksum
+ *
+ * Description:
+ *   Perform the checksum calculation over the iob data payload and
+ *   default checksum.
+ *
+ * Input Parameters:
+ *   dev   - The network driver instance.  The packet data is in the d_buf
+ *           of the device.
+ *   proto - The protocol being supported
+ *   iplen - The size of the IPv6 header.  This may be larger than
+ *           IPv6_HDRLEN the IPv6 header if IPv6 extension headers are
+ *           present.
+ *
+ * Returned Value:
+ *   The calculated checksum
+ *
+ ****************************************************************************/
+
+uint16_t ipv6_upperlayer_payload_chksum(FAR struct net_driver_s *dev,
+                                        unsigned int iplen, uint16_t sum);
+
+#endif /* CONFIG_NET_IPv6 */
+
 /****************************************************************************
  * Name: netdev_list_lock
  *
diff --git a/net/netdev/netdev_checksum.c b/net/netdev/netdev_checksum.c
index 24ad4ac9f8d..d2c2cac7fe3 100644
--- a/net/netdev/netdev_checksum.c
+++ b/net/netdev/netdev_checksum.c
@@ -194,4 +194,39 @@ int netdev_checksum_offset(FAR struct net_driver_s *dev)
   return offset;
 }
 
+/****************************************************************************
+ * Name: netdev_upperlayer_header_checksum
+ *
+ * Description:
+ *   get upperlayer header checksum with tcp/udp header.
+ *
+ * Input Parameters:
+ *   dev  -  The driver structure
+ *
+ * Returned Value:
+ *   The upperlayer header checksum
+ *
+ ****************************************************************************/
+
+uint16_t netdev_upperlayer_header_checksum(FAR struct net_driver_s *dev)
+{
+  if (IFF_IS_IPv6(dev->d_flags))
+    {
+      FAR struct ipv6_hdr_s *ipv6 = IPv6BUF;
+
+      return HTONS(ipv6_upperlayer_header_chksum(dev,
+                                                 ipv6->proto,
+                                                 IPv6_HDRLEN));
+    }
+  else
+    {
+      FAR struct ipv4_hdr_s *ipv4 = IPv4BUF;
+
+      return HTONS(ipv4_upperlayer_header_chksum(dev,
+                                                 ipv4->proto));
+    }
+
+  return 0;
+}
+
 #endif /* CONFIG_NETDEV_CHECKSUM */
diff --git a/net/tcp/tcp_send.c b/net/tcp/tcp_send.c
index 574691e935e..1eae474bba4 100644
--- a/net/tcp/tcp_send.c
+++ b/net/tcp/tcp_send.c
@@ -204,13 +204,6 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
         {
           tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
         }
-      else
-        {
-          uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
-                                                          IP_PROTO_TCP,
-                                                          IPv6_HDRLEN);
-          tcp->tcpchksum = HTONS(chksum);
-        }
 #endif
 
 #ifdef CONFIG_NET_STATISTICS
@@ -238,12 +231,6 @@ static void tcp_sendcommon(FAR struct net_driver_s *dev,
         {
           tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
         }
-      else
-        {
-          uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
-                                                          IP_PROTO_TCP);
-          tcp->tcpchksum = HTONS(chksum);
-        }
 #endif
 
 #ifdef CONFIG_NET_STATISTICS
@@ -530,13 +517,6 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
         {
           tcp->tcpchksum = ~tcp_ipv6_chksum(dev);
         }
-      else
-        {
-          uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
-                                                          IP_PROTO_TCP,
-                                                          IPv6_HDRLEN);
-          tcp->tcpchksum = HTONS(chksum);
-        }
 #endif
     }
 #endif /* CONFIG_NET_IPv6 */
@@ -560,12 +540,6 @@ void tcp_reset(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
         {
           tcp->tcpchksum = ~tcp_ipv4_chksum(dev);
         }
-      else
-        {
-          uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
-                                                          IP_PROTO_TCP);
-          tcp->tcpchksum = HTONS(chksum);
-        }
 #endif
     }
 #endif /* CONFIG_NET_IPv4 */
diff --git a/net/udp/udp_send.c b/net/udp/udp_send.c
index aaa1c5a09df..39bade48f0a 100644
--- a/net/udp/udp_send.c
+++ b/net/udp/udp_send.c
@@ -250,46 +250,30 @@ void udp_send(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
 #ifdef CONFIG_NET_UDP_CHECKSUMS
       /* Calculate UDP checksum. */
 
+      if ((dev->d_features & NETDEV_TX_CSUM) == 0)
+        {
 #ifdef CONFIG_NET_IPv4
 #ifdef CONFIG_NET_IPv6
-      if (IFF_IS_IPv4(dev->d_flags))
+          if (IFF_IS_IPv4(dev->d_flags))
 #endif
-        {
-          if ((dev->d_features & NETDEV_TX_CSUM) == 0)
             {
               udp->udpchksum = ~udp_ipv4_chksum(dev);
             }
-          else
-            {
-              uint16_t chksum = ipv4_upperlayer_header_chksum(dev,
-                                                              IP_PROTO_UDP);
-              udp->udpchksum = HTONS(chksum);
-            }
-        }
 #endif /* CONFIG_NET_IPv4 */
 
 #ifdef CONFIG_NET_IPv6
 #ifdef CONFIG_NET_IPv4
-      else
+          else
 #endif
-        {
-          if ((dev->d_features & NETDEV_TX_CSUM) == 0)
             {
               udp->udpchksum = ~udp_ipv6_chksum(dev);
             }
-          else
-            {
-              uint16_t chksum = ipv6_upperlayer_header_chksum(dev,
-                                                              IP_PROTO_UDP,
-                                                              IPv6_HDRLEN);
-              udp->udpchksum = HTONS(chksum);
-            }
-        }
 #endif /* CONFIG_NET_IPv6 */
 
-      if (udp->udpchksum == 0)
-        {
-          udp->udpchksum = 0xffff;
+          if (udp->udpchksum == 0)
+            {
+              udp->udpchksum = 0xffff;
+            }
         }
 #endif /* CONFIG_NET_UDP_CHECKSUMS */