162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __NITROX_REQ_H
362306a36Sopenharmony_ci#define __NITROX_REQ_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/dma-mapping.h>
662306a36Sopenharmony_ci#include <crypto/aes.h>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "nitrox_dev.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define PENDING_SIG	0xFFFFFFFFFFFFFFFFUL
1162306a36Sopenharmony_ci#define PRIO 4001
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_citypedef void (*sereq_completion_t)(void *req, int err);
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/**
1662306a36Sopenharmony_ci * struct gphdr - General purpose Header
1762306a36Sopenharmony_ci * @param0: first parameter.
1862306a36Sopenharmony_ci * @param1: second parameter.
1962306a36Sopenharmony_ci * @param2: third parameter.
2062306a36Sopenharmony_ci * @param3: fourth parameter.
2162306a36Sopenharmony_ci *
2262306a36Sopenharmony_ci * Params tell the iv and enc/dec data offsets.
2362306a36Sopenharmony_ci */
2462306a36Sopenharmony_cistruct gphdr {
2562306a36Sopenharmony_ci	__be16 param0;
2662306a36Sopenharmony_ci	__be16 param1;
2762306a36Sopenharmony_ci	__be16 param2;
2862306a36Sopenharmony_ci	__be16 param3;
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/**
3262306a36Sopenharmony_ci * struct se_req_ctrl - SE request information.
3362306a36Sopenharmony_ci * @arg: Minor number of the opcode
3462306a36Sopenharmony_ci * @ctxc: Context control.
3562306a36Sopenharmony_ci * @unca: Uncertainity enabled.
3662306a36Sopenharmony_ci * @info: Additional information for SE cores.
3762306a36Sopenharmony_ci * @ctxl: Context length in bytes.
3862306a36Sopenharmony_ci * @uddl: User defined data length
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_ciunion se_req_ctrl {
4162306a36Sopenharmony_ci	u64 value;
4262306a36Sopenharmony_ci	struct {
4362306a36Sopenharmony_ci		u64 raz	: 22;
4462306a36Sopenharmony_ci		u64 arg	: 8;
4562306a36Sopenharmony_ci		u64 ctxc : 2;
4662306a36Sopenharmony_ci		u64 unca : 1;
4762306a36Sopenharmony_ci		u64 info : 3;
4862306a36Sopenharmony_ci		u64 unc : 8;
4962306a36Sopenharmony_ci		u64 ctxl : 12;
5062306a36Sopenharmony_ci		u64 uddl : 8;
5162306a36Sopenharmony_ci	} s;
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define MAX_IV_LEN 16
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/**
5762306a36Sopenharmony_ci * struct se_crypto_request - SE crypto request structure.
5862306a36Sopenharmony_ci * @opcode: Request opcode (enc/dec)
5962306a36Sopenharmony_ci * @flags: flags from crypto subsystem
6062306a36Sopenharmony_ci * @ctx_handle: Crypto context handle.
6162306a36Sopenharmony_ci * @gph: GP Header
6262306a36Sopenharmony_ci * @ctrl: Request Information.
6362306a36Sopenharmony_ci * @orh: ORH address
6462306a36Sopenharmony_ci * @comp: completion address
6562306a36Sopenharmony_ci * @src: Input sglist
6662306a36Sopenharmony_ci * @dst: Output sglist
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_cistruct se_crypto_request {
6962306a36Sopenharmony_ci	u8 opcode;
7062306a36Sopenharmony_ci	gfp_t gfp;
7162306a36Sopenharmony_ci	u32 flags;
7262306a36Sopenharmony_ci	u64 ctx_handle;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	struct gphdr gph;
7562306a36Sopenharmony_ci	union se_req_ctrl ctrl;
7662306a36Sopenharmony_ci	u64 *orh;
7762306a36Sopenharmony_ci	u64 *comp;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	struct scatterlist *src;
8062306a36Sopenharmony_ci	struct scatterlist *dst;
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/* Crypto opcodes */
8462306a36Sopenharmony_ci#define FLEXI_CRYPTO_ENCRYPT_HMAC	0x33
8562306a36Sopenharmony_ci#define ENCRYPT	0
8662306a36Sopenharmony_ci#define DECRYPT 1
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/* IV from context */
8962306a36Sopenharmony_ci#define IV_FROM_CTX	0
9062306a36Sopenharmony_ci/* IV from Input data */
9162306a36Sopenharmony_ci#define IV_FROM_DPTR	1
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/**
9462306a36Sopenharmony_ci * cipher opcodes for firmware
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_cienum flexi_cipher {
9762306a36Sopenharmony_ci	CIPHER_NULL = 0,
9862306a36Sopenharmony_ci	CIPHER_3DES_CBC,
9962306a36Sopenharmony_ci	CIPHER_3DES_ECB,
10062306a36Sopenharmony_ci	CIPHER_AES_CBC,
10162306a36Sopenharmony_ci	CIPHER_AES_ECB,
10262306a36Sopenharmony_ci	CIPHER_AES_CFB,
10362306a36Sopenharmony_ci	CIPHER_AES_CTR,
10462306a36Sopenharmony_ci	CIPHER_AES_GCM,
10562306a36Sopenharmony_ci	CIPHER_AES_XTS,
10662306a36Sopenharmony_ci	CIPHER_AES_CCM,
10762306a36Sopenharmony_ci	CIPHER_AES_CBC_CTS,
10862306a36Sopenharmony_ci	CIPHER_AES_ECB_CTS,
10962306a36Sopenharmony_ci	CIPHER_INVALID
11062306a36Sopenharmony_ci};
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cienum flexi_auth {
11362306a36Sopenharmony_ci	AUTH_NULL = 0,
11462306a36Sopenharmony_ci	AUTH_MD5,
11562306a36Sopenharmony_ci	AUTH_SHA1,
11662306a36Sopenharmony_ci	AUTH_SHA2_SHA224,
11762306a36Sopenharmony_ci	AUTH_SHA2_SHA256,
11862306a36Sopenharmony_ci	AUTH_SHA2_SHA384,
11962306a36Sopenharmony_ci	AUTH_SHA2_SHA512,
12062306a36Sopenharmony_ci	AUTH_GMAC,
12162306a36Sopenharmony_ci	AUTH_INVALID
12262306a36Sopenharmony_ci};
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/**
12562306a36Sopenharmony_ci * struct crypto_keys - Crypto keys
12662306a36Sopenharmony_ci * @key: Encryption key or KEY1 for AES-XTS
12762306a36Sopenharmony_ci * @iv: Encryption IV or Tweak for AES-XTS
12862306a36Sopenharmony_ci */
12962306a36Sopenharmony_cistruct crypto_keys {
13062306a36Sopenharmony_ci	union {
13162306a36Sopenharmony_ci		u8 key[AES_MAX_KEY_SIZE];
13262306a36Sopenharmony_ci		u8 key1[AES_MAX_KEY_SIZE];
13362306a36Sopenharmony_ci	} u;
13462306a36Sopenharmony_ci	u8 iv[AES_BLOCK_SIZE];
13562306a36Sopenharmony_ci};
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/**
13862306a36Sopenharmony_ci * struct auth_keys - Authentication keys
13962306a36Sopenharmony_ci * @ipad: IPAD or KEY2 for AES-XTS
14062306a36Sopenharmony_ci * @opad: OPAD or AUTH KEY if auth_input_type = 1
14162306a36Sopenharmony_ci */
14262306a36Sopenharmony_cistruct auth_keys {
14362306a36Sopenharmony_ci	union {
14462306a36Sopenharmony_ci		u8 ipad[64];
14562306a36Sopenharmony_ci		u8 key2[64];
14662306a36Sopenharmony_ci	} u;
14762306a36Sopenharmony_ci	u8 opad[64];
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciunion fc_ctx_flags {
15162306a36Sopenharmony_ci	__be64 f;
15262306a36Sopenharmony_ci	u64 fu;
15362306a36Sopenharmony_ci	struct {
15462306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
15562306a36Sopenharmony_ci		u64 cipher_type	: 4;
15662306a36Sopenharmony_ci		u64 reserved_59	: 1;
15762306a36Sopenharmony_ci		u64 aes_keylen : 2;
15862306a36Sopenharmony_ci		u64 iv_source : 1;
15962306a36Sopenharmony_ci		u64 hash_type : 4;
16062306a36Sopenharmony_ci		u64 reserved_49_51 : 3;
16162306a36Sopenharmony_ci		u64 auth_input_type: 1;
16262306a36Sopenharmony_ci		u64 mac_len : 8;
16362306a36Sopenharmony_ci		u64 reserved_0_39 : 40;
16462306a36Sopenharmony_ci#else
16562306a36Sopenharmony_ci		u64 reserved_0_39 : 40;
16662306a36Sopenharmony_ci		u64 mac_len : 8;
16762306a36Sopenharmony_ci		u64 auth_input_type: 1;
16862306a36Sopenharmony_ci		u64 reserved_49_51 : 3;
16962306a36Sopenharmony_ci		u64 hash_type : 4;
17062306a36Sopenharmony_ci		u64 iv_source : 1;
17162306a36Sopenharmony_ci		u64 aes_keylen : 2;
17262306a36Sopenharmony_ci		u64 reserved_59	: 1;
17362306a36Sopenharmony_ci		u64 cipher_type	: 4;
17462306a36Sopenharmony_ci#endif
17562306a36Sopenharmony_ci	} w0;
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci/**
17862306a36Sopenharmony_ci * struct flexi_crypto_context - Crypto context
17962306a36Sopenharmony_ci * @cipher_type: Encryption cipher type
18062306a36Sopenharmony_ci * @aes_keylen: AES key length
18162306a36Sopenharmony_ci * @iv_source: Encryption IV source
18262306a36Sopenharmony_ci * @hash_type: Authentication type
18362306a36Sopenharmony_ci * @auth_input_type: Authentication input type
18462306a36Sopenharmony_ci *   1 - Authentication IV and KEY, microcode calculates OPAD/IPAD
18562306a36Sopenharmony_ci *   0 - Authentication OPAD/IPAD
18662306a36Sopenharmony_ci * @mac_len: mac length
18762306a36Sopenharmony_ci * @crypto: Crypto keys
18862306a36Sopenharmony_ci * @auth: Authentication keys
18962306a36Sopenharmony_ci */
19062306a36Sopenharmony_cistruct flexi_crypto_context {
19162306a36Sopenharmony_ci	union fc_ctx_flags flags;
19262306a36Sopenharmony_ci	struct crypto_keys crypto;
19362306a36Sopenharmony_ci	struct auth_keys auth;
19462306a36Sopenharmony_ci};
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistruct crypto_ctx_hdr {
19762306a36Sopenharmony_ci	struct dma_pool *pool;
19862306a36Sopenharmony_ci	dma_addr_t dma;
19962306a36Sopenharmony_ci	void *vaddr;
20062306a36Sopenharmony_ci};
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistruct nitrox_crypto_ctx {
20362306a36Sopenharmony_ci	struct nitrox_device *ndev;
20462306a36Sopenharmony_ci	union {
20562306a36Sopenharmony_ci		u64 ctx_handle;
20662306a36Sopenharmony_ci		struct flexi_crypto_context *fctx;
20762306a36Sopenharmony_ci	} u;
20862306a36Sopenharmony_ci	struct crypto_ctx_hdr *chdr;
20962306a36Sopenharmony_ci	sereq_completion_t callback;
21062306a36Sopenharmony_ci};
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistruct nitrox_kcrypt_request {
21362306a36Sopenharmony_ci	struct se_crypto_request creq;
21462306a36Sopenharmony_ci	u8 *src;
21562306a36Sopenharmony_ci	u8 *dst;
21662306a36Sopenharmony_ci	u8 *iv_out;
21762306a36Sopenharmony_ci};
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci/**
22062306a36Sopenharmony_ci * struct nitrox_aead_rctx - AEAD request context
22162306a36Sopenharmony_ci * @nkreq: Base request context
22262306a36Sopenharmony_ci * @cryptlen: Encryption/Decryption data length
22362306a36Sopenharmony_ci * @assoclen: AAD length
22462306a36Sopenharmony_ci * @srclen: Input buffer length
22562306a36Sopenharmony_ci * @dstlen: Output buffer length
22662306a36Sopenharmony_ci * @iv: IV data
22762306a36Sopenharmony_ci * @ivsize: IV data length
22862306a36Sopenharmony_ci * @flags: AEAD req flags
22962306a36Sopenharmony_ci * @ctx_handle: Device context handle
23062306a36Sopenharmony_ci * @src: Source sglist
23162306a36Sopenharmony_ci * @dst: Destination sglist
23262306a36Sopenharmony_ci * @ctrl_arg: Identifies the request type (ENCRYPT/DECRYPT)
23362306a36Sopenharmony_ci */
23462306a36Sopenharmony_cistruct nitrox_aead_rctx {
23562306a36Sopenharmony_ci	struct nitrox_kcrypt_request nkreq;
23662306a36Sopenharmony_ci	unsigned int cryptlen;
23762306a36Sopenharmony_ci	unsigned int assoclen;
23862306a36Sopenharmony_ci	unsigned int srclen;
23962306a36Sopenharmony_ci	unsigned int dstlen;
24062306a36Sopenharmony_ci	u8 *iv;
24162306a36Sopenharmony_ci	int ivsize;
24262306a36Sopenharmony_ci	u32 flags;
24362306a36Sopenharmony_ci	u64 ctx_handle;
24462306a36Sopenharmony_ci	struct scatterlist *src;
24562306a36Sopenharmony_ci	struct scatterlist *dst;
24662306a36Sopenharmony_ci	u8 ctrl_arg;
24762306a36Sopenharmony_ci};
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci/**
25062306a36Sopenharmony_ci * struct nitrox_rfc4106_rctx - rfc4106 cipher request context
25162306a36Sopenharmony_ci * @base: AEAD request context
25262306a36Sopenharmony_ci * @src: Source sglist
25362306a36Sopenharmony_ci * @dst: Destination sglist
25462306a36Sopenharmony_ci * @assoc: AAD
25562306a36Sopenharmony_ci */
25662306a36Sopenharmony_cistruct nitrox_rfc4106_rctx {
25762306a36Sopenharmony_ci	struct nitrox_aead_rctx base;
25862306a36Sopenharmony_ci	struct scatterlist src[3];
25962306a36Sopenharmony_ci	struct scatterlist dst[3];
26062306a36Sopenharmony_ci	u8 assoc[20];
26162306a36Sopenharmony_ci};
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci/**
26462306a36Sopenharmony_ci * struct pkt_instr_hdr - Packet Instruction Header
26562306a36Sopenharmony_ci * @g: Gather used
26662306a36Sopenharmony_ci *   When [G] is set and [GSZ] != 0, the instruction is
26762306a36Sopenharmony_ci *   indirect gather instruction.
26862306a36Sopenharmony_ci *   When [G] is set and [GSZ] = 0, the instruction is
26962306a36Sopenharmony_ci *   direct gather instruction.
27062306a36Sopenharmony_ci * @gsz: Number of pointers in the indirect gather list
27162306a36Sopenharmony_ci * @ihi: When set hardware duplicates the 1st 8 bytes of pkt_instr_hdr
27262306a36Sopenharmony_ci *   and adds them to the packet after the pkt_instr_hdr but before any UDD
27362306a36Sopenharmony_ci * @ssz: Not used by the input hardware. But can become slc_store_int[SSZ]
27462306a36Sopenharmony_ci *   when [IHI] is set.
27562306a36Sopenharmony_ci * @fsz: The number of front data bytes directly included in the
27662306a36Sopenharmony_ci *   PCIe instruction.
27762306a36Sopenharmony_ci * @tlen: The length of the input packet in bytes, include:
27862306a36Sopenharmony_ci *   - 16B pkt_hdr
27962306a36Sopenharmony_ci *   - Inline context bytes if any,
28062306a36Sopenharmony_ci *   - UDD if any,
28162306a36Sopenharmony_ci *   - packet payload bytes
28262306a36Sopenharmony_ci */
28362306a36Sopenharmony_ciunion pkt_instr_hdr {
28462306a36Sopenharmony_ci	__be64 bev;
28562306a36Sopenharmony_ci	u64 value;
28662306a36Sopenharmony_ci	struct {
28762306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
28862306a36Sopenharmony_ci		u64 raz_48_63 : 16;
28962306a36Sopenharmony_ci		u64 g : 1;
29062306a36Sopenharmony_ci		u64 gsz	: 7;
29162306a36Sopenharmony_ci		u64 ihi	: 1;
29262306a36Sopenharmony_ci		u64 ssz	: 7;
29362306a36Sopenharmony_ci		u64 raz_30_31 : 2;
29462306a36Sopenharmony_ci		u64 fsz	: 6;
29562306a36Sopenharmony_ci		u64 raz_16_23 : 8;
29662306a36Sopenharmony_ci		u64 tlen : 16;
29762306a36Sopenharmony_ci#else
29862306a36Sopenharmony_ci		u64 tlen : 16;
29962306a36Sopenharmony_ci		u64 raz_16_23 : 8;
30062306a36Sopenharmony_ci		u64 fsz	: 6;
30162306a36Sopenharmony_ci		u64 raz_30_31 : 2;
30262306a36Sopenharmony_ci		u64 ssz	: 7;
30362306a36Sopenharmony_ci		u64 ihi	: 1;
30462306a36Sopenharmony_ci		u64 gsz	: 7;
30562306a36Sopenharmony_ci		u64 g : 1;
30662306a36Sopenharmony_ci		u64 raz_48_63 : 16;
30762306a36Sopenharmony_ci#endif
30862306a36Sopenharmony_ci	} s;
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci/**
31262306a36Sopenharmony_ci * struct pkt_hdr - Packet Input Header
31362306a36Sopenharmony_ci * @opcode: Request opcode (Major)
31462306a36Sopenharmony_ci * @arg: Request opcode (Minor)
31562306a36Sopenharmony_ci * @ctxc: Context control.
31662306a36Sopenharmony_ci * @unca: When set [UNC] is the uncertainty count for an input packet.
31762306a36Sopenharmony_ci *        The hardware uses uncertainty counts to predict
31862306a36Sopenharmony_ci *        output buffer use and avoid deadlock.
31962306a36Sopenharmony_ci * @info: Not used by input hardware. Available for use
32062306a36Sopenharmony_ci *        during SE processing.
32162306a36Sopenharmony_ci * @destport: The expected destination port/ring/channel for the packet.
32262306a36Sopenharmony_ci * @unc: Uncertainty count for an input packet.
32362306a36Sopenharmony_ci * @grp: SE group that will process the input packet.
32462306a36Sopenharmony_ci * @ctxl: Context Length in 64-bit words.
32562306a36Sopenharmony_ci * @uddl: User-defined data (UDD) length in bytes.
32662306a36Sopenharmony_ci * @ctxp: Context pointer. CTXP<63,2:0> must be zero in all cases.
32762306a36Sopenharmony_ci */
32862306a36Sopenharmony_ciunion pkt_hdr {
32962306a36Sopenharmony_ci	__be64 bev[2];
33062306a36Sopenharmony_ci	u64 value[2];
33162306a36Sopenharmony_ci	struct {
33262306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
33362306a36Sopenharmony_ci		u64 opcode : 8;
33462306a36Sopenharmony_ci		u64 arg	: 8;
33562306a36Sopenharmony_ci		u64 ctxc : 2;
33662306a36Sopenharmony_ci		u64 unca : 1;
33762306a36Sopenharmony_ci		u64 raz_44 : 1;
33862306a36Sopenharmony_ci		u64 info : 3;
33962306a36Sopenharmony_ci		u64 destport : 9;
34062306a36Sopenharmony_ci		u64 unc	: 8;
34162306a36Sopenharmony_ci		u64 raz_19_23 : 5;
34262306a36Sopenharmony_ci		u64 grp	: 3;
34362306a36Sopenharmony_ci		u64 raz_15 : 1;
34462306a36Sopenharmony_ci		u64 ctxl : 7;
34562306a36Sopenharmony_ci		u64 uddl : 8;
34662306a36Sopenharmony_ci#else
34762306a36Sopenharmony_ci		u64 uddl : 8;
34862306a36Sopenharmony_ci		u64 ctxl : 7;
34962306a36Sopenharmony_ci		u64 raz_15 : 1;
35062306a36Sopenharmony_ci		u64 grp	: 3;
35162306a36Sopenharmony_ci		u64 raz_19_23 : 5;
35262306a36Sopenharmony_ci		u64 unc	: 8;
35362306a36Sopenharmony_ci		u64 destport : 9;
35462306a36Sopenharmony_ci		u64 info : 3;
35562306a36Sopenharmony_ci		u64 raz_44 : 1;
35662306a36Sopenharmony_ci		u64 unca : 1;
35762306a36Sopenharmony_ci		u64 ctxc : 2;
35862306a36Sopenharmony_ci		u64 arg	: 8;
35962306a36Sopenharmony_ci		u64 opcode : 8;
36062306a36Sopenharmony_ci#endif
36162306a36Sopenharmony_ci		__be64 ctxp;
36262306a36Sopenharmony_ci	} s;
36362306a36Sopenharmony_ci};
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci/**
36662306a36Sopenharmony_ci * struct slc_store_info - Solicited Paceket Output Store Information.
36762306a36Sopenharmony_ci * @ssz: The number of scatterlist pointers for the solicited output port
36862306a36Sopenharmony_ci *       packet.
36962306a36Sopenharmony_ci * @rptr: The result pointer for the solicited output port packet.
37062306a36Sopenharmony_ci *        If [SSZ]=0, [RPTR] must point directly to a buffer on the remote
37162306a36Sopenharmony_ci *        host that is large enough to hold the entire output packet.
37262306a36Sopenharmony_ci *        If [SSZ]!=0, [RPTR] must point to an array of ([SSZ]+3)/4
37362306a36Sopenharmony_ci *        sglist components at [RPTR] on the remote host.
37462306a36Sopenharmony_ci */
37562306a36Sopenharmony_ciunion slc_store_info {
37662306a36Sopenharmony_ci	__be64 bev[2];
37762306a36Sopenharmony_ci	u64 value[2];
37862306a36Sopenharmony_ci	struct {
37962306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
38062306a36Sopenharmony_ci		u64 raz_39_63 : 25;
38162306a36Sopenharmony_ci		u64 ssz	: 7;
38262306a36Sopenharmony_ci		u64 raz_0_31 : 32;
38362306a36Sopenharmony_ci#else
38462306a36Sopenharmony_ci		u64 raz_0_31 : 32;
38562306a36Sopenharmony_ci		u64 ssz	: 7;
38662306a36Sopenharmony_ci		u64 raz_39_63 : 25;
38762306a36Sopenharmony_ci#endif
38862306a36Sopenharmony_ci		__be64 rptr;
38962306a36Sopenharmony_ci	} s;
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci/**
39362306a36Sopenharmony_ci * struct nps_pkt_instr - NPS Packet Instruction of SE cores.
39462306a36Sopenharmony_ci * @dptr0 : Input pointer points to buffer in remote host.
39562306a36Sopenharmony_ci * @ih: Packet Instruction Header (8 bytes)
39662306a36Sopenharmony_ci * @irh: Packet Input Header (16 bytes)
39762306a36Sopenharmony_ci * @slc: Solicited Packet Output Store Information (16 bytes)
39862306a36Sopenharmony_ci * @fdata: Front data
39962306a36Sopenharmony_ci *
40062306a36Sopenharmony_ci * 64-Byte Instruction Format
40162306a36Sopenharmony_ci */
40262306a36Sopenharmony_cistruct nps_pkt_instr {
40362306a36Sopenharmony_ci	__be64 dptr0;
40462306a36Sopenharmony_ci	union pkt_instr_hdr ih;
40562306a36Sopenharmony_ci	union pkt_hdr irh;
40662306a36Sopenharmony_ci	union slc_store_info slc;
40762306a36Sopenharmony_ci	u64 fdata[2];
40862306a36Sopenharmony_ci};
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci/**
41162306a36Sopenharmony_ci * struct aqmq_command_s - The 32 byte command for AE processing.
41262306a36Sopenharmony_ci * @opcode: Request opcode
41362306a36Sopenharmony_ci * @param1: Request control parameter 1
41462306a36Sopenharmony_ci * @param2: Request control parameter 2
41562306a36Sopenharmony_ci * @dlen: Input length
41662306a36Sopenharmony_ci * @dptr: Input pointer points to buffer in remote host
41762306a36Sopenharmony_ci * @rptr: Result pointer points to buffer in remote host
41862306a36Sopenharmony_ci * @grp: AQM Group (0..7)
41962306a36Sopenharmony_ci * @cptr: Context pointer
42062306a36Sopenharmony_ci */
42162306a36Sopenharmony_cistruct aqmq_command_s {
42262306a36Sopenharmony_ci	__be16 opcode;
42362306a36Sopenharmony_ci	__be16 param1;
42462306a36Sopenharmony_ci	__be16 param2;
42562306a36Sopenharmony_ci	__be16 dlen;
42662306a36Sopenharmony_ci	__be64 dptr;
42762306a36Sopenharmony_ci	__be64 rptr;
42862306a36Sopenharmony_ci	union {
42962306a36Sopenharmony_ci		__be64 word3;
43062306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
43162306a36Sopenharmony_ci		u64 grp : 3;
43262306a36Sopenharmony_ci		u64 cptr : 61;
43362306a36Sopenharmony_ci#else
43462306a36Sopenharmony_ci		u64 cptr : 61;
43562306a36Sopenharmony_ci		u64 grp : 3;
43662306a36Sopenharmony_ci#endif
43762306a36Sopenharmony_ci	};
43862306a36Sopenharmony_ci};
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci/**
44162306a36Sopenharmony_ci * struct ctx_hdr - Book keeping data about the crypto context
44262306a36Sopenharmony_ci * @pool: Pool used to allocate crypto context
44362306a36Sopenharmony_ci * @dma: Base DMA address of the crypto context
44462306a36Sopenharmony_ci * @ctx_dma: Actual usable crypto context for NITROX
44562306a36Sopenharmony_ci */
44662306a36Sopenharmony_cistruct ctx_hdr {
44762306a36Sopenharmony_ci	struct dma_pool *pool;
44862306a36Sopenharmony_ci	dma_addr_t dma;
44962306a36Sopenharmony_ci	dma_addr_t ctx_dma;
45062306a36Sopenharmony_ci};
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci/*
45362306a36Sopenharmony_ci * struct sglist_component - SG list component format
45462306a36Sopenharmony_ci * @len0: The number of bytes at [PTR0] on the remote host.
45562306a36Sopenharmony_ci * @len1: The number of bytes at [PTR1] on the remote host.
45662306a36Sopenharmony_ci * @len2: The number of bytes at [PTR2] on the remote host.
45762306a36Sopenharmony_ci * @len3: The number of bytes at [PTR3] on the remote host.
45862306a36Sopenharmony_ci * @dma0: First pointer point to buffer in remote host.
45962306a36Sopenharmony_ci * @dma1: Second pointer point to buffer in remote host.
46062306a36Sopenharmony_ci * @dma2: Third pointer point to buffer in remote host.
46162306a36Sopenharmony_ci * @dma3: Fourth pointer point to buffer in remote host.
46262306a36Sopenharmony_ci */
46362306a36Sopenharmony_cistruct nitrox_sgcomp {
46462306a36Sopenharmony_ci	__be16 len[4];
46562306a36Sopenharmony_ci	__be64 dma[4];
46662306a36Sopenharmony_ci};
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci/*
46962306a36Sopenharmony_ci * strutct nitrox_sgtable - SG list information
47062306a36Sopenharmony_ci * @sgmap_cnt: Number of buffers mapped
47162306a36Sopenharmony_ci * @total_bytes: Total bytes in sglist.
47262306a36Sopenharmony_ci * @sgcomp_len: Total sglist components length.
47362306a36Sopenharmony_ci * @sgcomp_dma: DMA address of sglist component.
47462306a36Sopenharmony_ci * @sg: crypto request buffer.
47562306a36Sopenharmony_ci * @sgcomp: sglist component for NITROX.
47662306a36Sopenharmony_ci */
47762306a36Sopenharmony_cistruct nitrox_sgtable {
47862306a36Sopenharmony_ci	u8 sgmap_cnt;
47962306a36Sopenharmony_ci	u16 total_bytes;
48062306a36Sopenharmony_ci	u32 sgcomp_len;
48162306a36Sopenharmony_ci	dma_addr_t sgcomp_dma;
48262306a36Sopenharmony_ci	struct scatterlist *sg;
48362306a36Sopenharmony_ci	struct nitrox_sgcomp *sgcomp;
48462306a36Sopenharmony_ci};
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci/* Response Header Length */
48762306a36Sopenharmony_ci#define ORH_HLEN	8
48862306a36Sopenharmony_ci/* Completion bytes Length */
48962306a36Sopenharmony_ci#define COMP_HLEN	8
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistruct resp_hdr {
49262306a36Sopenharmony_ci	u64 *orh;
49362306a36Sopenharmony_ci	u64 *completion;
49462306a36Sopenharmony_ci};
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_citypedef void (*completion_t)(void *arg, int err);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci/**
49962306a36Sopenharmony_ci * struct nitrox_softreq - Represents the NIROX Request.
50062306a36Sopenharmony_ci * @response: response list entry
50162306a36Sopenharmony_ci * @backlog: Backlog list entry
50262306a36Sopenharmony_ci * @ndev: Device used to submit the request
50362306a36Sopenharmony_ci * @cmdq: Command queue for submission
50462306a36Sopenharmony_ci * @resp: Response headers
50562306a36Sopenharmony_ci * @instr: 64B instruction
50662306a36Sopenharmony_ci * @in: SG table for input
50762306a36Sopenharmony_ci * @out SG table for output
50862306a36Sopenharmony_ci * @tstamp: Request submitted time in jiffies
50962306a36Sopenharmony_ci * @callback: callback after request completion/timeout
51062306a36Sopenharmony_ci * @cb_arg: callback argument
51162306a36Sopenharmony_ci */
51262306a36Sopenharmony_cistruct nitrox_softreq {
51362306a36Sopenharmony_ci	struct list_head response;
51462306a36Sopenharmony_ci	struct list_head backlog;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	u32 flags;
51762306a36Sopenharmony_ci	gfp_t gfp;
51862306a36Sopenharmony_ci	atomic_t status;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	struct nitrox_device *ndev;
52162306a36Sopenharmony_ci	struct nitrox_cmdq *cmdq;
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	struct nps_pkt_instr instr;
52462306a36Sopenharmony_ci	struct resp_hdr resp;
52562306a36Sopenharmony_ci	struct nitrox_sgtable in;
52662306a36Sopenharmony_ci	struct nitrox_sgtable out;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	unsigned long tstamp;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	completion_t callback;
53162306a36Sopenharmony_ci	void *cb_arg;
53262306a36Sopenharmony_ci};
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_cistatic inline int flexi_aes_keylen(int keylen)
53562306a36Sopenharmony_ci{
53662306a36Sopenharmony_ci	int aes_keylen;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	switch (keylen) {
53962306a36Sopenharmony_ci	case AES_KEYSIZE_128:
54062306a36Sopenharmony_ci		aes_keylen = 1;
54162306a36Sopenharmony_ci		break;
54262306a36Sopenharmony_ci	case AES_KEYSIZE_192:
54362306a36Sopenharmony_ci		aes_keylen = 2;
54462306a36Sopenharmony_ci		break;
54562306a36Sopenharmony_ci	case AES_KEYSIZE_256:
54662306a36Sopenharmony_ci		aes_keylen = 3;
54762306a36Sopenharmony_ci		break;
54862306a36Sopenharmony_ci	default:
54962306a36Sopenharmony_ci		aes_keylen = -EINVAL;
55062306a36Sopenharmony_ci		break;
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci	return aes_keylen;
55362306a36Sopenharmony_ci}
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_cistatic inline void *alloc_req_buf(int nents, int extralen, gfp_t gfp)
55662306a36Sopenharmony_ci{
55762306a36Sopenharmony_ci	size_t size;
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	size = sizeof(struct scatterlist) * nents;
56062306a36Sopenharmony_ci	size += extralen;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	return kzalloc(size, gfp);
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci/**
56662306a36Sopenharmony_ci * create_single_sg - Point SG entry to the data
56762306a36Sopenharmony_ci * @sg:		Destination SG list
56862306a36Sopenharmony_ci * @buf:	Data
56962306a36Sopenharmony_ci * @buflen:	Data length
57062306a36Sopenharmony_ci *
57162306a36Sopenharmony_ci * Returns next free entry in the destination SG list
57262306a36Sopenharmony_ci **/
57362306a36Sopenharmony_cistatic inline struct scatterlist *create_single_sg(struct scatterlist *sg,
57462306a36Sopenharmony_ci						   void *buf, int buflen)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	sg_set_buf(sg, buf, buflen);
57762306a36Sopenharmony_ci	sg++;
57862306a36Sopenharmony_ci	return sg;
57962306a36Sopenharmony_ci}
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci/**
58262306a36Sopenharmony_ci * create_multi_sg - Create multiple sg entries with buflen data length from
58362306a36Sopenharmony_ci *		     source sglist
58462306a36Sopenharmony_ci * @to_sg:	Destination SG list
58562306a36Sopenharmony_ci * @from_sg:	Source SG list
58662306a36Sopenharmony_ci * @buflen:	Data length
58762306a36Sopenharmony_ci *
58862306a36Sopenharmony_ci * Returns next free entry in the destination SG list
58962306a36Sopenharmony_ci **/
59062306a36Sopenharmony_cistatic inline struct scatterlist *create_multi_sg(struct scatterlist *to_sg,
59162306a36Sopenharmony_ci						  struct scatterlist *from_sg,
59262306a36Sopenharmony_ci						  int buflen)
59362306a36Sopenharmony_ci{
59462306a36Sopenharmony_ci	struct scatterlist *sg = to_sg;
59562306a36Sopenharmony_ci	unsigned int sglen;
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	for (; buflen && from_sg; buflen -= sglen) {
59862306a36Sopenharmony_ci		sglen = from_sg->length;
59962306a36Sopenharmony_ci		if (sglen > buflen)
60062306a36Sopenharmony_ci			sglen = buflen;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci		sg_set_buf(sg, sg_virt(from_sg), sglen);
60362306a36Sopenharmony_ci		from_sg = sg_next(from_sg);
60462306a36Sopenharmony_ci		sg++;
60562306a36Sopenharmony_ci	}
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	return sg;
60862306a36Sopenharmony_ci}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_cistatic inline void set_orh_value(u64 *orh)
61162306a36Sopenharmony_ci{
61262306a36Sopenharmony_ci	WRITE_ONCE(*orh, PENDING_SIG);
61362306a36Sopenharmony_ci}
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_cistatic inline void set_comp_value(u64 *comp)
61662306a36Sopenharmony_ci{
61762306a36Sopenharmony_ci	WRITE_ONCE(*comp, PENDING_SIG);
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_cistatic inline int alloc_src_req_buf(struct nitrox_kcrypt_request *nkreq,
62162306a36Sopenharmony_ci				    int nents, int ivsize)
62262306a36Sopenharmony_ci{
62362306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci	nkreq->src = alloc_req_buf(nents, ivsize, creq->gfp);
62662306a36Sopenharmony_ci	if (!nkreq->src)
62762306a36Sopenharmony_ci		return -ENOMEM;
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	return 0;
63062306a36Sopenharmony_ci}
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistatic inline void nitrox_creq_copy_iv(char *dst, char *src, int size)
63362306a36Sopenharmony_ci{
63462306a36Sopenharmony_ci	memcpy(dst, src, size);
63562306a36Sopenharmony_ci}
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_cistatic inline struct scatterlist *nitrox_creq_src_sg(char *iv, int ivsize)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	return (struct scatterlist *)(iv + ivsize);
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_cistatic inline void nitrox_creq_set_src_sg(struct nitrox_kcrypt_request *nkreq,
64362306a36Sopenharmony_ci					  int nents, int ivsize,
64462306a36Sopenharmony_ci					  struct scatterlist *src, int buflen)
64562306a36Sopenharmony_ci{
64662306a36Sopenharmony_ci	char *iv = nkreq->src;
64762306a36Sopenharmony_ci	struct scatterlist *sg;
64862306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci	creq->src = nitrox_creq_src_sg(iv, ivsize);
65162306a36Sopenharmony_ci	sg = creq->src;
65262306a36Sopenharmony_ci	sg_init_table(sg, nents);
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	/* Input format:
65562306a36Sopenharmony_ci	 * +----+----------------+
65662306a36Sopenharmony_ci	 * | IV | SRC sg entries |
65762306a36Sopenharmony_ci	 * +----+----------------+
65862306a36Sopenharmony_ci	 */
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci	/* IV */
66162306a36Sopenharmony_ci	sg = create_single_sg(sg, iv, ivsize);
66262306a36Sopenharmony_ci	/* SRC entries */
66362306a36Sopenharmony_ci	create_multi_sg(sg, src, buflen);
66462306a36Sopenharmony_ci}
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_cistatic inline int alloc_dst_req_buf(struct nitrox_kcrypt_request *nkreq,
66762306a36Sopenharmony_ci				    int nents)
66862306a36Sopenharmony_ci{
66962306a36Sopenharmony_ci	int extralen = ORH_HLEN + COMP_HLEN;
67062306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	nkreq->dst = alloc_req_buf(nents, extralen, creq->gfp);
67362306a36Sopenharmony_ci	if (!nkreq->dst)
67462306a36Sopenharmony_ci		return -ENOMEM;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	return 0;
67762306a36Sopenharmony_ci}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_cistatic inline void nitrox_creq_set_orh(struct nitrox_kcrypt_request *nkreq)
68062306a36Sopenharmony_ci{
68162306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	creq->orh = (u64 *)(nkreq->dst);
68462306a36Sopenharmony_ci	set_orh_value(creq->orh);
68562306a36Sopenharmony_ci}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_cistatic inline void nitrox_creq_set_comp(struct nitrox_kcrypt_request *nkreq)
68862306a36Sopenharmony_ci{
68962306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_ci	creq->comp = (u64 *)(nkreq->dst + ORH_HLEN);
69262306a36Sopenharmony_ci	set_comp_value(creq->comp);
69362306a36Sopenharmony_ci}
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_cistatic inline struct scatterlist *nitrox_creq_dst_sg(char *dst)
69662306a36Sopenharmony_ci{
69762306a36Sopenharmony_ci	return (struct scatterlist *)(dst + ORH_HLEN + COMP_HLEN);
69862306a36Sopenharmony_ci}
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_cistatic inline void nitrox_creq_set_dst_sg(struct nitrox_kcrypt_request *nkreq,
70162306a36Sopenharmony_ci					  int nents, int ivsize,
70262306a36Sopenharmony_ci					  struct scatterlist *dst, int buflen)
70362306a36Sopenharmony_ci{
70462306a36Sopenharmony_ci	struct se_crypto_request *creq = &nkreq->creq;
70562306a36Sopenharmony_ci	struct scatterlist *sg;
70662306a36Sopenharmony_ci	char *iv = nkreq->src;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	creq->dst = nitrox_creq_dst_sg(nkreq->dst);
70962306a36Sopenharmony_ci	sg = creq->dst;
71062306a36Sopenharmony_ci	sg_init_table(sg, nents);
71162306a36Sopenharmony_ci
71262306a36Sopenharmony_ci	/* Output format:
71362306a36Sopenharmony_ci	 * +-----+----+----------------+-----------------+
71462306a36Sopenharmony_ci	 * | ORH | IV | DST sg entries | COMPLETION Bytes|
71562306a36Sopenharmony_ci	 * +-----+----+----------------+-----------------+
71662306a36Sopenharmony_ci	 */
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	/* ORH */
71962306a36Sopenharmony_ci	sg = create_single_sg(sg, creq->orh, ORH_HLEN);
72062306a36Sopenharmony_ci	/* IV */
72162306a36Sopenharmony_ci	sg = create_single_sg(sg, iv, ivsize);
72262306a36Sopenharmony_ci	/* DST entries */
72362306a36Sopenharmony_ci	sg = create_multi_sg(sg, dst, buflen);
72462306a36Sopenharmony_ci	/* COMPLETION Bytes */
72562306a36Sopenharmony_ci	create_single_sg(sg, creq->comp, COMP_HLEN);
72662306a36Sopenharmony_ci}
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci#endif /* __NITROX_REQ_H */
729