Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 66 additions & 86 deletions include/nuttx/net/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -339,6 +344,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
*/
Expand Down Expand Up @@ -901,46 +910,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
*
Expand All @@ -963,52 +932,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
*
Expand Down Expand Up @@ -1359,4 +1282,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 */
3 changes: 2 additions & 1 deletion net/devif/ipv4_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,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. */

Expand Down
1 change: 1 addition & 0 deletions net/inet/ipv4_build_header.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions net/netdev/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,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})
9 changes: 9 additions & 0 deletions net/netdev/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,13 @@ config NETDOWN_NOTIFIER
notifier, but was developed specifically to support SIGHUP poll()
logic.

config NETDEV_CHECKSUM
bool "netdev hardware checksum"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool "netdev hardware checksum"
bool "Enable support to netdev checksum in Hardware"

default n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is something that depends on chip supporting it, shouldn't it have a "depends on ARCH_HAVE_NETDEV_CHKSUM_HW" ?

@xiaoxiang781216 @raiden00pl please comment

---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
4 changes: 4 additions & 0 deletions net/netdev/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
93 changes: 93 additions & 0 deletions net/netdev/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,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 */

#undef EXTERN
#ifdef __cplusplus
}
Expand Down
Loading
Loading