1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2022-2024 Chelsio Communications, Inc.
5 * Written by: John Baldwin <jhb@FreeBSD.org>
6 */
7
8#ifndef __LIBNVMF_INTERNAL_H__
9#define __LIBNVMF_INTERNAL_H__
10
11#include <sys/queue.h>
12
13struct nvmf_transport_ops {
14	/* Association management. */
15	struct nvmf_association *(*allocate_association)(bool controller,
16	    const struct nvmf_association_params *params);
17	void (*update_association)(struct nvmf_association *na,
18	    const struct nvme_controller_data *cdata);
19	void (*free_association)(struct nvmf_association *na);
20
21	/* Queue pair management. */
22	struct nvmf_qpair *(*allocate_qpair)(struct nvmf_association *na,
23	    const struct nvmf_qpair_params *params);
24	void (*free_qpair)(struct nvmf_qpair *qp);
25
26	/* Create params for kernel handoff. */
27	int (*kernel_handoff_params)(struct nvmf_qpair *qp,
28	    struct nvmf_handoff_qpair_params *qparams);
29
30	/* Capsule operations. */
31	struct nvmf_capsule *(*allocate_capsule)(struct nvmf_qpair *qp);
32	void (*free_capsule)(struct nvmf_capsule *nc);
33	int (*transmit_capsule)(struct nvmf_capsule *nc);
34	int (*receive_capsule)(struct nvmf_qpair *qp,
35	    struct nvmf_capsule **ncp);
36	uint8_t (*validate_command_capsule)(const struct nvmf_capsule *nc);
37
38	/* Transferring controller data. */
39	size_t (*capsule_data_len)(const struct nvmf_capsule *nc);
40	int (*receive_controller_data)(const struct nvmf_capsule *nc,
41	    uint32_t data_offset, void *buf, size_t len);
42	int (*send_controller_data)(const struct nvmf_capsule *nc,
43	    const void *buf, size_t len);
44};
45
46struct nvmf_association {
47	struct nvmf_transport_ops *na_ops;
48	enum nvmf_trtype na_trtype;
49	bool na_controller;
50
51	struct nvmf_association_params na_params;
52
53	/* Each qpair holds a reference on an association. */
54	u_int na_refs;
55
56	char *na_last_error;
57};
58
59struct nvmf_qpair {
60	struct nvmf_association *nq_association;
61	bool nq_admin;
62
63	uint16_t nq_cid;	/* host only */
64
65	/*
66	 * Queue sizes.  This assumes the same size for both the
67	 * completion and submission queues within a pair.
68	 */
69	u_int	nq_qsize;
70
71	/* Flow control management for submission queues. */
72	bool nq_flow_control;
73	uint16_t nq_sqhd;
74	uint16_t nq_sqtail;	/* host only */
75
76	/* Value in response to/from CONNECT. */
77	uint16_t nq_cntlid;
78
79	uint32_t nq_kato;	/* valid on admin queue only */
80
81	TAILQ_HEAD(, nvmf_capsule) nq_rx_capsules;
82};
83
84struct nvmf_capsule {
85	struct nvmf_qpair *nc_qpair;
86
87	/* Either a SQE or CQE. */
88	union {
89		struct nvme_command nc_sqe;
90		struct nvme_completion nc_cqe;
91	};
92	int	nc_qe_len;
93
94	/*
95	 * Is SQHD in received capsule valid?  False for locally-
96	 * synthesized responses.
97	 */
98	bool	nc_sqhd_valid;
99
100	/* Data buffer. */
101	bool	nc_send_data;
102	void	*nc_data;
103	size_t	nc_data_len;
104
105	TAILQ_ENTRY(nvmf_capsule) nc_link;
106};
107
108extern struct nvmf_transport_ops tcp_ops;
109
110void	na_clear_error(struct nvmf_association *na);
111void	na_error(struct nvmf_association *na, const char *fmt, ...);
112
113int	nvmf_kernel_handoff_params(struct nvmf_qpair *qp,
114    struct nvmf_handoff_qpair_params *qparams);
115
116#endif /* !__LIBNVMF_INTERNAL_H__ */
117