18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2016 ARM Ltd.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#ifndef __ASM_CHECKSUM_H
68c2ecf20Sopenharmony_ci#define __ASM_CHECKSUM_H
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/in6.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#define _HAVE_ARCH_IPV6_CSUM
118c2ecf20Sopenharmony_ci__sum16 csum_ipv6_magic(const struct in6_addr *saddr,
128c2ecf20Sopenharmony_ci			const struct in6_addr *daddr,
138c2ecf20Sopenharmony_ci			__u32 len, __u8 proto, __wsum sum);
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic inline __sum16 csum_fold(__wsum csum)
168c2ecf20Sopenharmony_ci{
178c2ecf20Sopenharmony_ci	u32 sum = (__force u32)csum;
188c2ecf20Sopenharmony_ci	sum += (sum >> 16) | (sum << 16);
198c2ecf20Sopenharmony_ci	return ~(__force __sum16)(sum >> 16);
208c2ecf20Sopenharmony_ci}
218c2ecf20Sopenharmony_ci#define csum_fold csum_fold
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cistatic inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	__uint128_t tmp;
268c2ecf20Sopenharmony_ci	u64 sum;
278c2ecf20Sopenharmony_ci	int n = ihl; /* we want it signed */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	tmp = *(const __uint128_t *)iph;
308c2ecf20Sopenharmony_ci	iph += 16;
318c2ecf20Sopenharmony_ci	n -= 4;
328c2ecf20Sopenharmony_ci	tmp += ((tmp >> 64) | (tmp << 64));
338c2ecf20Sopenharmony_ci	sum = tmp >> 64;
348c2ecf20Sopenharmony_ci	do {
358c2ecf20Sopenharmony_ci		sum += *(const u32 *)iph;
368c2ecf20Sopenharmony_ci		iph += 4;
378c2ecf20Sopenharmony_ci	} while (--n > 0);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	sum += ((sum >> 32) | (sum << 32));
408c2ecf20Sopenharmony_ci	return csum_fold((__force u32)(sum >> 32));
418c2ecf20Sopenharmony_ci}
428c2ecf20Sopenharmony_ci#define ip_fast_csum ip_fast_csum
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ciextern unsigned int do_csum(const unsigned char *buff, int len);
458c2ecf20Sopenharmony_ci#define do_csum do_csum
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#include <asm-generic/checksum.h>
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci#endif	/* __ASM_CHECKSUM_H */
50