/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

#ifndef __OBD_CKSUM
#define __OBD_CKSUM
#include "../../include/linux/libcfs/libcfs.h"
#include "../../include/linux/libcfs/libcfs_crypto.h"
#include "lustre/lustre_idl.h"

static inline unsigned char cksum_obd2cfs(enum cksum_type cksum_type)
{
	switch (cksum_type) {
	case OBD_CKSUM_CRC32:
		return CFS_HASH_ALG_CRC32;
	case OBD_CKSUM_ADLER:
		return CFS_HASH_ALG_ADLER32;
	case OBD_CKSUM_CRC32C:
		return CFS_HASH_ALG_CRC32C;
	default:
		CERROR("Unknown checksum type (%x)!!!\n", cksum_type);
		LBUG();
	}
	return 0;
}

/* The OBD_FL_CKSUM_* flags is packed into 5 bits of o_flags, since there can
 * only be a single checksum type per RPC.
 *
 * The OBD_CHECKSUM_* type bits passed in ocd_cksum_types are a 32-bit bitmask
 * since they need to represent the full range of checksum algorithms that
 * both the client and server can understand.
 *
 * In case of an unsupported types/flags we fall back to ADLER
 * because that is supported by all clients since 1.8
 *
 * In case multiple algorithms are supported the best one is used.
 */
static inline u32 cksum_type_pack(enum cksum_type cksum_type)
{
	unsigned int    performance = 0, tmp;
	u32		flag = OBD_FL_CKSUM_ADLER;

	if (cksum_type & OBD_CKSUM_CRC32) {
		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32));
		if (tmp > performance) {
			performance = tmp;
			flag = OBD_FL_CKSUM_CRC32;
		}
	}
	if (cksum_type & OBD_CKSUM_CRC32C) {
		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C));
		if (tmp > performance) {
			performance = tmp;
			flag = OBD_FL_CKSUM_CRC32C;
		}
	}
	if (cksum_type & OBD_CKSUM_ADLER) {
		tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER));
		if (tmp > performance) {
			performance = tmp;
			flag = OBD_FL_CKSUM_ADLER;
		}
	}
	if (unlikely(cksum_type && !(cksum_type & (OBD_CKSUM_CRC32C |
						   OBD_CKSUM_CRC32 |
						   OBD_CKSUM_ADLER))))
		CWARN("unknown cksum type %x\n", cksum_type);

	return flag;
}

static inline enum cksum_type cksum_type_unpack(u32 o_flags)
{
	switch (o_flags & OBD_FL_CKSUM_ALL) {
	case OBD_FL_CKSUM_CRC32C:
		return OBD_CKSUM_CRC32C;
	case OBD_FL_CKSUM_CRC32:
		return OBD_CKSUM_CRC32;
	default:
		break;
	}

	return OBD_CKSUM_ADLER;
}

/* Return a bitmask of the checksum types supported on this system.
 * 1.8 supported ADLER it is base and not depend on hw
 * Client uses all available local algos
 */
static inline enum cksum_type cksum_types_supported_client(void)
{
	enum cksum_type ret = OBD_CKSUM_ADLER;

	CDEBUG(D_INFO, "Crypto hash speed: crc %d, crc32c %d, adler %d\n",
	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)),
	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)),
	       cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_ADLER)));

	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32C)) > 0)
		ret |= OBD_CKSUM_CRC32C;
	if (cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)) > 0)
		ret |= OBD_CKSUM_CRC32;

	return ret;
}

/* Select the best checksum algorithm among those supplied in the cksum_types
 * input.
 *
 * Currently, calling cksum_type_pack() with a mask will return the fastest
 * checksum type due to its benchmarking at libcfs module load.
 * Caution is advised, however, since what is fastest on a single client may
 * not be the fastest or most efficient algorithm on the server.
 */
static inline enum cksum_type cksum_type_select(enum cksum_type cksum_types)
{
	return cksum_type_unpack(cksum_type_pack(cksum_types));
}

/* Checksum algorithm names. Must be defined in the same order as the
 * OBD_CKSUM_* flags.
 */
#define DECLARE_CKSUM_NAME char *cksum_name[] = {"crc32", "adler", "crc32c"}

#endif /* __OBD_H */
