From 13a83f4ab30bd75831261e6b197903244f1ad753 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 14 Jun 2026 17:15:55 +0100 Subject: [PATCH] [s390x] Add optimised TCP/IP checksumming Add an S/390 assembly language implementation of TCP/IP checksumming, using the hardware "cksm" instruction to first calculate the 32-bit one's complement checksum and then folding down to 16 bits. Use an inline function since the whole checksum calculation (including folding) requires only six instructions. Signed-off-by: Michael Brown --- src/arch/s390x/include/bits/tcpip.h | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/arch/s390x/include/bits/tcpip.h diff --git a/src/arch/s390x/include/bits/tcpip.h b/src/arch/s390x/include/bits/tcpip.h new file mode 100644 index 000000000..423b1a176 --- /dev/null +++ b/src/arch/s390x/include/bits/tcpip.h @@ -0,0 +1,41 @@ +#ifndef _BITS_TCPIP_H +#define _BITS_TCPIP_H + +/** @file + * + * Transport-network layer interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +/** + * Calculate continued TCP/IP checkum + * + * @v partial Checksum of already-summed data, in network byte order + * @v data Data buffer + * @v len Length of data buffer + * @ret cksum Updated checksum, in network byte order + */ +static inline __attribute__ (( always_inline )) uint16_t +tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) { + struct s390x_pointer_pair pair = { data, len }; + unsigned int cksum; + + __asm__ ( /* Calculate 32-bit checksum */ + "\n1:\n\t" + "cksm %0, %1\n\t" + "jo 1b\n\t" + /* Fold down to 16 bits */ + "risbgz %1, %0, 32, 47, 16\n\t" + "alr %0, %1\n\t" + "srl %0, 16\n\t" + "alcr %0, %N1\n\t" + : "=&r" ( cksum ), + "+r" ( pair ) + : "0" ( ~partial ) ); + + return ~cksum; +} + +#endif /* _BITS_TCPIP_H */