162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2015-2017 Oracle. All rights reserved.
462306a36Sopenharmony_ci * Copyright (c) 2003-2007 Network Appliance, Inc. All rights reserved.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * This software is available to you under a choice of one of two
762306a36Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the BSD-type
1062306a36Sopenharmony_ci * license below:
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
1362306a36Sopenharmony_ci * modification, are permitted provided that the following conditions
1462306a36Sopenharmony_ci * are met:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *      Redistributions of source code must retain the above copyright
1762306a36Sopenharmony_ci *      notice, this list of conditions and the following disclaimer.
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci *      Redistributions in binary form must reproduce the above
2062306a36Sopenharmony_ci *      copyright notice, this list of conditions and the following
2162306a36Sopenharmony_ci *      disclaimer in the documentation and/or other materials provided
2262306a36Sopenharmony_ci *      with the distribution.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci *      Neither the name of the Network Appliance, Inc. nor the names of
2562306a36Sopenharmony_ci *      its contributors may be used to endorse or promote products
2662306a36Sopenharmony_ci *      derived from this software without specific prior written
2762306a36Sopenharmony_ci *      permission.
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3062306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3162306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3262306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3362306a36Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3462306a36Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3562306a36Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3662306a36Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3762306a36Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3862306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3962306a36Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#ifndef _LINUX_SUNRPC_RPC_RDMA_H
4362306a36Sopenharmony_ci#define _LINUX_SUNRPC_RPC_RDMA_H
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include <linux/types.h>
4662306a36Sopenharmony_ci#include <linux/bitops.h>
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define RPCRDMA_VERSION		1
4962306a36Sopenharmony_ci#define rpcrdma_version		cpu_to_be32(RPCRDMA_VERSION)
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cienum {
5262306a36Sopenharmony_ci	RPCRDMA_V1_DEF_INLINE_SIZE	= 1024,
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/*
5662306a36Sopenharmony_ci * XDR sizes, in quads
5762306a36Sopenharmony_ci */
5862306a36Sopenharmony_cienum {
5962306a36Sopenharmony_ci	rpcrdma_fixed_maxsz	= 4,
6062306a36Sopenharmony_ci	rpcrdma_segment_maxsz	= 4,
6162306a36Sopenharmony_ci	rpcrdma_readseg_maxsz	= 1 + rpcrdma_segment_maxsz,
6262306a36Sopenharmony_ci	rpcrdma_readchunk_maxsz	= 1 + rpcrdma_readseg_maxsz,
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/*
6662306a36Sopenharmony_ci * Smallest RPC/RDMA header: rm_xid through rm_type, then rm_nochunks
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_ci#define RPCRDMA_HDRLEN_MIN	(sizeof(__be32) * 7)
6962306a36Sopenharmony_ci#define RPCRDMA_HDRLEN_ERR	(sizeof(__be32) * 5)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cienum rpcrdma_errcode {
7262306a36Sopenharmony_ci	ERR_VERS = 1,
7362306a36Sopenharmony_ci	ERR_CHUNK = 2
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cienum rpcrdma_proc {
7762306a36Sopenharmony_ci	RDMA_MSG = 0,		/* An RPC call or reply msg */
7862306a36Sopenharmony_ci	RDMA_NOMSG = 1,		/* An RPC call or reply msg - separate body */
7962306a36Sopenharmony_ci	RDMA_MSGP = 2,		/* An RPC call or reply msg with padding */
8062306a36Sopenharmony_ci	RDMA_DONE = 3,		/* Client signals reply completion */
8162306a36Sopenharmony_ci	RDMA_ERROR = 4		/* An RPC RDMA encoding error */
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci#define rdma_msg	cpu_to_be32(RDMA_MSG)
8562306a36Sopenharmony_ci#define rdma_nomsg	cpu_to_be32(RDMA_NOMSG)
8662306a36Sopenharmony_ci#define rdma_msgp	cpu_to_be32(RDMA_MSGP)
8762306a36Sopenharmony_ci#define rdma_done	cpu_to_be32(RDMA_DONE)
8862306a36Sopenharmony_ci#define rdma_error	cpu_to_be32(RDMA_ERROR)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define err_vers	cpu_to_be32(ERR_VERS)
9162306a36Sopenharmony_ci#define err_chunk	cpu_to_be32(ERR_CHUNK)
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/*
9462306a36Sopenharmony_ci * Private extension to RPC-over-RDMA Version One.
9562306a36Sopenharmony_ci * Message passed during RDMA-CM connection set-up.
9662306a36Sopenharmony_ci *
9762306a36Sopenharmony_ci * Add new fields at the end, and don't permute existing
9862306a36Sopenharmony_ci * fields.
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_cistruct rpcrdma_connect_private {
10162306a36Sopenharmony_ci	__be32			cp_magic;
10262306a36Sopenharmony_ci	u8			cp_version;
10362306a36Sopenharmony_ci	u8			cp_flags;
10462306a36Sopenharmony_ci	u8			cp_send_size;
10562306a36Sopenharmony_ci	u8			cp_recv_size;
10662306a36Sopenharmony_ci} __packed;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#define rpcrdma_cmp_magic	__cpu_to_be32(0xf6ab0e18)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cienum {
11162306a36Sopenharmony_ci	RPCRDMA_CMP_VERSION		= 1,
11262306a36Sopenharmony_ci	RPCRDMA_CMP_F_SND_W_INV_OK	= BIT(0),
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic inline u8
11662306a36Sopenharmony_cirpcrdma_encode_buffer_size(unsigned int size)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return (size >> 10) - 1;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic inline unsigned int
12262306a36Sopenharmony_cirpcrdma_decode_buffer_size(u8 val)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	return ((unsigned int)val + 1) << 10;
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/**
12862306a36Sopenharmony_ci * xdr_encode_rdma_segment - Encode contents of an RDMA segment
12962306a36Sopenharmony_ci * @p: Pointer into a send buffer
13062306a36Sopenharmony_ci * @handle: The RDMA handle to encode
13162306a36Sopenharmony_ci * @length: The RDMA length to encode
13262306a36Sopenharmony_ci * @offset: The RDMA offset to encode
13362306a36Sopenharmony_ci *
13462306a36Sopenharmony_ci * Return value:
13562306a36Sopenharmony_ci *   Pointer to the XDR position that follows the encoded RDMA segment
13662306a36Sopenharmony_ci */
13762306a36Sopenharmony_cistatic inline __be32 *xdr_encode_rdma_segment(__be32 *p, u32 handle,
13862306a36Sopenharmony_ci					      u32 length, u64 offset)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	*p++ = cpu_to_be32(handle);
14162306a36Sopenharmony_ci	*p++ = cpu_to_be32(length);
14262306a36Sopenharmony_ci	return xdr_encode_hyper(p, offset);
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/**
14662306a36Sopenharmony_ci * xdr_encode_read_segment - Encode contents of a Read segment
14762306a36Sopenharmony_ci * @p: Pointer into a send buffer
14862306a36Sopenharmony_ci * @position: The position to encode
14962306a36Sopenharmony_ci * @handle: The RDMA handle to encode
15062306a36Sopenharmony_ci * @length: The RDMA length to encode
15162306a36Sopenharmony_ci * @offset: The RDMA offset to encode
15262306a36Sopenharmony_ci *
15362306a36Sopenharmony_ci * Return value:
15462306a36Sopenharmony_ci *   Pointer to the XDR position that follows the encoded Read segment
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_cistatic inline __be32 *xdr_encode_read_segment(__be32 *p, u32 position,
15762306a36Sopenharmony_ci					      u32 handle, u32 length,
15862306a36Sopenharmony_ci					      u64 offset)
15962306a36Sopenharmony_ci{
16062306a36Sopenharmony_ci	*p++ = cpu_to_be32(position);
16162306a36Sopenharmony_ci	return xdr_encode_rdma_segment(p, handle, length, offset);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/**
16562306a36Sopenharmony_ci * xdr_decode_rdma_segment - Decode contents of an RDMA segment
16662306a36Sopenharmony_ci * @p: Pointer to the undecoded RDMA segment
16762306a36Sopenharmony_ci * @handle: Upon return, the RDMA handle
16862306a36Sopenharmony_ci * @length: Upon return, the RDMA length
16962306a36Sopenharmony_ci * @offset: Upon return, the RDMA offset
17062306a36Sopenharmony_ci *
17162306a36Sopenharmony_ci * Return value:
17262306a36Sopenharmony_ci *   Pointer to the XDR item that follows the RDMA segment
17362306a36Sopenharmony_ci */
17462306a36Sopenharmony_cistatic inline __be32 *xdr_decode_rdma_segment(__be32 *p, u32 *handle,
17562306a36Sopenharmony_ci					      u32 *length, u64 *offset)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	*handle = be32_to_cpup(p++);
17862306a36Sopenharmony_ci	*length = be32_to_cpup(p++);
17962306a36Sopenharmony_ci	return xdr_decode_hyper(p, offset);
18062306a36Sopenharmony_ci}
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci/**
18362306a36Sopenharmony_ci * xdr_decode_read_segment - Decode contents of a Read segment
18462306a36Sopenharmony_ci * @p: Pointer to the undecoded Read segment
18562306a36Sopenharmony_ci * @position: Upon return, the segment's position
18662306a36Sopenharmony_ci * @handle: Upon return, the RDMA handle
18762306a36Sopenharmony_ci * @length: Upon return, the RDMA length
18862306a36Sopenharmony_ci * @offset: Upon return, the RDMA offset
18962306a36Sopenharmony_ci *
19062306a36Sopenharmony_ci * Return value:
19162306a36Sopenharmony_ci *   Pointer to the XDR item that follows the Read segment
19262306a36Sopenharmony_ci */
19362306a36Sopenharmony_cistatic inline __be32 *xdr_decode_read_segment(__be32 *p, u32 *position,
19462306a36Sopenharmony_ci					      u32 *handle, u32 *length,
19562306a36Sopenharmony_ci					      u64 *offset)
19662306a36Sopenharmony_ci{
19762306a36Sopenharmony_ci	*position = be32_to_cpup(p++);
19862306a36Sopenharmony_ci	return xdr_decode_rdma_segment(p, handle, length, offset);
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci#endif				/* _LINUX_SUNRPC_RPC_RDMA_H */
202