Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * INET		An implementation of the TCP/IP protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *		operating system.  INET is implemented using the  BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *		interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *		MIPS specific IP/TCP/UDP checksumming routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *		Lots of code moved from tcp.c and ip.c; see those files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *		for more names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <net/checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define addc(_t,_r)                     \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	__asm__ __volatile__ (          \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) "       add             %0, %1, %0\n"   \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) "       addc            %0, %%r0, %0\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	: "=r"(_t)                      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	: "r"(_r), "0"(_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static inline unsigned short from32to16(unsigned int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	/* 32 bits --> 16 bits + carry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	x = (x & 0xffff) + (x >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	/* 16 bits + carry --> 16 bits including carry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	x = (x & 0xffff) + (x >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	return (unsigned short)x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static inline unsigned int do_csum(const unsigned char * buff, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	int odd, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	unsigned int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (len <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	odd = 1 & (unsigned long) buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (odd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		result = be16_to_cpu(*buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		buff++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	count = len >> 1;		/* nr of 16-bit words.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (2 & (unsigned long) buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			result += *(unsigned short *) buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			buff += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		count >>= 1;		/* nr of 32-bit words.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			while (count >= 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 				unsigned int r1, r2, r3, r4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				r1 = *(unsigned int *)(buff + 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 				r2 = *(unsigned int *)(buff + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 				r3 = *(unsigned int *)(buff + 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 				r4 = *(unsigned int *)(buff + 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 				addc(result, r1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 				addc(result, r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 				addc(result, r3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				addc(result, r4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 				count -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 				buff += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 				unsigned int w = *(unsigned int *) buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 				count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				buff += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				addc(result, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			result = (result & 0xffff) + (result >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		if (len & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			result += *(unsigned short *) buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			buff += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (len & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		result += le16_to_cpu(*buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	result = from32to16(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (odd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		result = swab16(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * computes a partial checksum, e.g. for TCP/UDP fragments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * why bother folding?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __wsum csum_partial(const void *buff, int len, __wsum sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	unsigned int result = do_csum(buff, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	addc(result, sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return (__force __wsum)from32to16(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) EXPORT_SYMBOL(csum_partial);