File Index
Files and directories
Sign in
FILE

checksum.h

File preview with syntax highlighting.

linux-6.19.14/arch/s390/include/asm/checksum.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*
  3 *    S390 fast network checksum routines
  4 *
  5 *  S390 version
  6 *    Copyright IBM Corp. 1999
  7 *    Author(s): Ulrich Hild        (first version)
  8 *               Martin Schwidefsky (heavily optimized CKSM version)
  9 *               D.J. Barrow        (third attempt) 
 10 */
 11
 12#ifndef _S390_CHECKSUM_H
 13#define _S390_CHECKSUM_H
 14
 15#include <linux/instrumented.h>
 16#include <linux/kmsan-checks.h>
 17#include <linux/in6.h>
 18
 19static inline __wsum cksm(const void *buff, int len, __wsum sum)
 20{
 21	union register_pair rp = {
 22		.even = (unsigned long)buff,
 23		.odd = (unsigned long)len,
 24	};
 25
 26	instrument_read(buff, len);
 27	kmsan_check_memory(buff, len);
 28	asm volatile(
 29		"0:	cksm	%[sum],%[rp]\n"
 30		"	jo	0b"
 31		: [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory");
 32	return sum;
 33}
 34
 35__wsum csum_partial(const void *buff, int len, __wsum sum);
 36
 37#define _HAVE_ARCH_CSUM_AND_COPY
 38__wsum csum_partial_copy_nocheck(const void *src, void *dst, int len);
 39
 40/*
 41 * Fold a partial checksum without adding pseudo headers.
 42 */
 43static inline __sum16 csum_fold(__wsum sum)
 44{
 45	u32 csum = (__force u32) sum;
 46
 47	csum += (csum >> 16) | (csum << 16);
 48	csum >>= 16;
 49	return (__force __sum16) ~csum;
 50}
 51
 52/*
 53 * This is a version of ip_compute_csum() optimized for IP headers,
 54 * which always checksums on 4 octet boundaries.
 55 */
 56static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 57{
 58	__u64 csum = 0;
 59	__u32 *ptr = (u32 *)iph;
 60
 61	csum += *ptr++;
 62	csum += *ptr++;
 63	csum += *ptr++;
 64	csum += *ptr++;
 65	ihl -= 4;
 66	while (ihl--)
 67		csum += *ptr++;
 68	csum += (csum >> 32) | (csum << 32);
 69	return csum_fold((__force __wsum)(csum >> 32));
 70}
 71
 72/*
 73 * Computes the checksum of the TCP/UDP pseudo-header.
 74 * Returns a 32-bit checksum.
 75 */
 76static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
 77					__u8 proto, __wsum sum)
 78{
 79	__u64 csum = (__force __u64)sum;
 80
 81	csum += (__force __u32)saddr;
 82	csum += (__force __u32)daddr;
 83	csum += len;
 84	csum += proto;
 85	csum += (csum >> 32) | (csum << 32);
 86	return (__force __wsum)(csum >> 32);
 87}
 88
 89/*
 90 * Computes the checksum of the TCP/UDP pseudo-header.
 91 * Returns a 16-bit checksum, already complemented.
 92 */
 93static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
 94					__u8 proto, __wsum sum)
 95{
 96	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
 97}
 98
 99/*
100 * Used for miscellaneous IP-like checksums, mainly icmp.
101 */
102static inline __sum16 ip_compute_csum(const void *buff, int len)
103{
104	return csum_fold(csum_partial(buff, len, 0));
105}
106
107#define _HAVE_ARCH_IPV6_CSUM
108static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
109				      const struct in6_addr *daddr,
110				      __u32 len, __u8 proto, __wsum csum)
111{
112	__u64 sum = (__force __u64)csum;
113
114	sum += (__force __u32)saddr->s6_addr32[0];
115	sum += (__force __u32)saddr->s6_addr32[1];
116	sum += (__force __u32)saddr->s6_addr32[2];
117	sum += (__force __u32)saddr->s6_addr32[3];
118	sum += (__force __u32)daddr->s6_addr32[0];
119	sum += (__force __u32)daddr->s6_addr32[1];
120	sum += (__force __u32)daddr->s6_addr32[2];
121	sum += (__force __u32)daddr->s6_addr32[3];
122	sum += len;
123	sum += proto;
124	sum += (sum >> 32) | (sum << 32);
125	return csum_fold((__force __wsum)(sum >> 32));
126}
127
128#endif /* _S390_CHECKSUM_H */
~/ Read-only file preview.