162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#ifdef __KERNEL__
362306a36Sopenharmony_ci# include <linux/crush/hash.h>
462306a36Sopenharmony_ci#else
562306a36Sopenharmony_ci# include "hash.h"
662306a36Sopenharmony_ci#endif
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * Robert Jenkins' function for mixing 32-bit values
1062306a36Sopenharmony_ci * https://burtleburtle.net/bob/hash/evahash.html
1162306a36Sopenharmony_ci * a, b = random bits, c = input and output
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#define crush_hashmix(a, b, c) do {			\
1462306a36Sopenharmony_ci		a = a-b;  a = a-c;  a = a^(c>>13);	\
1562306a36Sopenharmony_ci		b = b-c;  b = b-a;  b = b^(a<<8);	\
1662306a36Sopenharmony_ci		c = c-a;  c = c-b;  c = c^(b>>13);	\
1762306a36Sopenharmony_ci		a = a-b;  a = a-c;  a = a^(c>>12);	\
1862306a36Sopenharmony_ci		b = b-c;  b = b-a;  b = b^(a<<16);	\
1962306a36Sopenharmony_ci		c = c-a;  c = c-b;  c = c^(b>>5);	\
2062306a36Sopenharmony_ci		a = a-b;  a = a-c;  a = a^(c>>3);	\
2162306a36Sopenharmony_ci		b = b-c;  b = b-a;  b = b^(a<<10);	\
2262306a36Sopenharmony_ci		c = c-a;  c = c-b;  c = c^(b>>15);	\
2362306a36Sopenharmony_ci	} while (0)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define crush_hash_seed 1315423911
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1(__u32 a)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	__u32 hash = crush_hash_seed ^ a;
3062306a36Sopenharmony_ci	__u32 b = a;
3162306a36Sopenharmony_ci	__u32 x = 231232;
3262306a36Sopenharmony_ci	__u32 y = 1232;
3362306a36Sopenharmony_ci	crush_hashmix(b, x, hash);
3462306a36Sopenharmony_ci	crush_hashmix(y, a, hash);
3562306a36Sopenharmony_ci	return hash;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_2(__u32 a, __u32 b)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	__u32 hash = crush_hash_seed ^ a ^ b;
4162306a36Sopenharmony_ci	__u32 x = 231232;
4262306a36Sopenharmony_ci	__u32 y = 1232;
4362306a36Sopenharmony_ci	crush_hashmix(a, b, hash);
4462306a36Sopenharmony_ci	crush_hashmix(x, a, hash);
4562306a36Sopenharmony_ci	crush_hashmix(b, y, hash);
4662306a36Sopenharmony_ci	return hash;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_3(__u32 a, __u32 b, __u32 c)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	__u32 hash = crush_hash_seed ^ a ^ b ^ c;
5262306a36Sopenharmony_ci	__u32 x = 231232;
5362306a36Sopenharmony_ci	__u32 y = 1232;
5462306a36Sopenharmony_ci	crush_hashmix(a, b, hash);
5562306a36Sopenharmony_ci	crush_hashmix(c, x, hash);
5662306a36Sopenharmony_ci	crush_hashmix(y, a, hash);
5762306a36Sopenharmony_ci	crush_hashmix(b, x, hash);
5862306a36Sopenharmony_ci	crush_hashmix(y, c, hash);
5962306a36Sopenharmony_ci	return hash;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_4(__u32 a, __u32 b, __u32 c, __u32 d)
6362306a36Sopenharmony_ci{
6462306a36Sopenharmony_ci	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d;
6562306a36Sopenharmony_ci	__u32 x = 231232;
6662306a36Sopenharmony_ci	__u32 y = 1232;
6762306a36Sopenharmony_ci	crush_hashmix(a, b, hash);
6862306a36Sopenharmony_ci	crush_hashmix(c, d, hash);
6962306a36Sopenharmony_ci	crush_hashmix(a, x, hash);
7062306a36Sopenharmony_ci	crush_hashmix(y, b, hash);
7162306a36Sopenharmony_ci	crush_hashmix(c, x, hash);
7262306a36Sopenharmony_ci	crush_hashmix(y, d, hash);
7362306a36Sopenharmony_ci	return hash;
7462306a36Sopenharmony_ci}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistatic __u32 crush_hash32_rjenkins1_5(__u32 a, __u32 b, __u32 c, __u32 d,
7762306a36Sopenharmony_ci				      __u32 e)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	__u32 hash = crush_hash_seed ^ a ^ b ^ c ^ d ^ e;
8062306a36Sopenharmony_ci	__u32 x = 231232;
8162306a36Sopenharmony_ci	__u32 y = 1232;
8262306a36Sopenharmony_ci	crush_hashmix(a, b, hash);
8362306a36Sopenharmony_ci	crush_hashmix(c, d, hash);
8462306a36Sopenharmony_ci	crush_hashmix(e, x, hash);
8562306a36Sopenharmony_ci	crush_hashmix(y, a, hash);
8662306a36Sopenharmony_ci	crush_hashmix(b, x, hash);
8762306a36Sopenharmony_ci	crush_hashmix(y, c, hash);
8862306a36Sopenharmony_ci	crush_hashmix(d, x, hash);
8962306a36Sopenharmony_ci	crush_hashmix(y, e, hash);
9062306a36Sopenharmony_ci	return hash;
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci__u32 crush_hash32(int type, __u32 a)
9562306a36Sopenharmony_ci{
9662306a36Sopenharmony_ci	switch (type) {
9762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
9862306a36Sopenharmony_ci		return crush_hash32_rjenkins1(a);
9962306a36Sopenharmony_ci	default:
10062306a36Sopenharmony_ci		return 0;
10162306a36Sopenharmony_ci	}
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci__u32 crush_hash32_2(int type, __u32 a, __u32 b)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	switch (type) {
10762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
10862306a36Sopenharmony_ci		return crush_hash32_rjenkins1_2(a, b);
10962306a36Sopenharmony_ci	default:
11062306a36Sopenharmony_ci		return 0;
11162306a36Sopenharmony_ci	}
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci__u32 crush_hash32_3(int type, __u32 a, __u32 b, __u32 c)
11562306a36Sopenharmony_ci{
11662306a36Sopenharmony_ci	switch (type) {
11762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
11862306a36Sopenharmony_ci		return crush_hash32_rjenkins1_3(a, b, c);
11962306a36Sopenharmony_ci	default:
12062306a36Sopenharmony_ci		return 0;
12162306a36Sopenharmony_ci	}
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci__u32 crush_hash32_4(int type, __u32 a, __u32 b, __u32 c, __u32 d)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	switch (type) {
12762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
12862306a36Sopenharmony_ci		return crush_hash32_rjenkins1_4(a, b, c, d);
12962306a36Sopenharmony_ci	default:
13062306a36Sopenharmony_ci		return 0;
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci__u32 crush_hash32_5(int type, __u32 a, __u32 b, __u32 c, __u32 d, __u32 e)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	switch (type) {
13762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
13862306a36Sopenharmony_ci		return crush_hash32_rjenkins1_5(a, b, c, d, e);
13962306a36Sopenharmony_ci	default:
14062306a36Sopenharmony_ci		return 0;
14162306a36Sopenharmony_ci	}
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciconst char *crush_hash_name(int type)
14562306a36Sopenharmony_ci{
14662306a36Sopenharmony_ci	switch (type) {
14762306a36Sopenharmony_ci	case CRUSH_HASH_RJENKINS1:
14862306a36Sopenharmony_ci		return "rjenkins1";
14962306a36Sopenharmony_ci	default:
15062306a36Sopenharmony_ci		return "unknown";
15162306a36Sopenharmony_ci	}
15262306a36Sopenharmony_ci}
153