xref: /spdk/lib/nvmf/nvmf_fc.h (revision 7192849ed24874f3e9cc31e8a33a9b32c49b9506)
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (c) 2018-2019 Broadcom.  All Rights Reserved.
5  *   The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef __NVMF_FC_H__
35 #define __NVMF_FC_H__
36 
37 #include "spdk/nvme.h"
38 #include "spdk/nvmf.h"
39 #include "spdk/assert.h"
40 #include "spdk/nvme_spec.h"
41 #include "spdk/nvmf_fc_spec.h"
42 #include "spdk/thread.h"
43 #include "nvmf_internal.h"
44 
45 #define SPDK_NVMF_FC_TR_ADDR_LEN 64
46 #define NVMF_FC_INVALID_CONN_ID UINT64_MAX
47 
48 #define SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE 256
49 #define SPDK_MAX_NUM_OF_FC_PORTS 32
50 #define SPDK_NVMF_PORT_ID_MAX_LEN 32
51 
52 /*
53  * FC HWQP pointer
54  */
55 typedef void *spdk_nvmf_fc_lld_hwqp_t;
56 
57 /*
58  * FC HW port states.
59  */
60 enum spdk_fc_port_state {
61 	SPDK_FC_PORT_OFFLINE = 0,
62 	SPDK_FC_PORT_ONLINE = 1,
63 	SPDK_FC_PORT_QUIESCED = 2,
64 };
65 
66 enum spdk_fc_hwqp_state {
67 	SPDK_FC_HWQP_OFFLINE = 0,
68 	SPDK_FC_HWQP_ONLINE = 1,
69 };
70 
71 /*
72  * NVMF FC Object state
73  * Add all the generic states of the object here.
74  * Specific object states can be added separately
75  */
76 enum spdk_nvmf_fc_object_state {
77 	SPDK_NVMF_FC_OBJECT_CREATED = 0,
78 	SPDK_NVMF_FC_OBJECT_TO_BE_DELETED = 1,
79 	SPDK_NVMF_FC_OBJECT_ZOMBIE = 2,      /* Partial Create or Delete  */
80 };
81 
82 /*
83  * FC request state
84  */
85 enum spdk_nvmf_fc_request_state {
86 	SPDK_NVMF_FC_REQ_INIT = 0,
87 	SPDK_NVMF_FC_REQ_READ_BDEV,
88 	SPDK_NVMF_FC_REQ_READ_XFER,
89 	SPDK_NVMF_FC_REQ_READ_RSP,
90 	SPDK_NVMF_FC_REQ_WRITE_BUFFS,
91 	SPDK_NVMF_FC_REQ_WRITE_XFER,
92 	SPDK_NVMF_FC_REQ_WRITE_BDEV,
93 	SPDK_NVMF_FC_REQ_WRITE_RSP,
94 	SPDK_NVMF_FC_REQ_NONE_BDEV,
95 	SPDK_NVMF_FC_REQ_NONE_RSP,
96 	SPDK_NVMF_FC_REQ_SUCCESS,
97 	SPDK_NVMF_FC_REQ_FAILED,
98 	SPDK_NVMF_FC_REQ_ABORTED,
99 	SPDK_NVMF_FC_REQ_BDEV_ABORTED,
100 	SPDK_NVMF_FC_REQ_PENDING,
101 	SPDK_NVMF_FC_REQ_MAX_STATE,
102 };
103 
104 /*
105  * Generic DMA buffer descriptor
106  */
107 struct spdk_nvmf_fc_buffer_desc {
108 	void *virt;
109 	uint64_t phys;
110 	size_t len;
111 
112 	/* Internal */
113 	uint32_t buf_index;
114 };
115 
116 /*
117  * ABTS hadling context
118  */
119 struct spdk_nvmf_fc_abts_ctx {
120 	bool handled;
121 	uint16_t hwqps_responded;
122 	uint16_t rpi;
123 	uint16_t oxid;
124 	uint16_t rxid;
125 	struct spdk_nvmf_fc_nport *nport;
126 	uint16_t nport_hdl;
127 	uint8_t port_hdl;
128 	void *abts_poller_args;
129 	void *sync_poller_args;
130 	int num_hwqps;
131 	bool queue_synced;
132 	uint64_t u_id;
133 	struct spdk_nvmf_fc_hwqp *ls_hwqp;
134 	uint16_t fcp_rq_id;
135 };
136 
137 /*
138  * NVME FC transport errors
139  */
140 struct spdk_nvmf_fc_errors {
141 	uint32_t no_xchg;
142 	uint32_t nport_invalid;
143 	uint32_t unknown_frame;
144 	uint32_t wqe_cmplt_err;
145 	uint32_t wqe_write_err;
146 	uint32_t rq_status_err;
147 	uint32_t rq_buf_len_err;
148 	uint32_t rq_id_err;
149 	uint32_t rq_index_err;
150 	uint32_t invalid_cq_type;
151 	uint32_t invalid_cq_id;
152 	uint32_t fc_req_buf_err;
153 	uint32_t buf_alloc_err;
154 	uint32_t unexpected_err;
155 	uint32_t nvme_cmd_iu_err;
156 	uint32_t nvme_cmd_xfer_err;
157 	uint32_t queue_entry_invalid;
158 	uint32_t invalid_conn_err;
159 	uint32_t fcp_rsp_failure;
160 	uint32_t write_failed;
161 	uint32_t read_failed;
162 	uint32_t rport_invalid;
163 	uint32_t num_aborted;
164 	uint32_t num_abts_sent;
165 };
166 
167 /*
168  *  Send Single Request/Response Sequence.
169  */
170 struct spdk_nvmf_fc_srsr_bufs {
171 	void *rqst;
172 	size_t rqst_len;
173 	void *rsp;
174 	size_t rsp_len;
175 	uint16_t rpi;
176 };
177 
178 /*
179  * Struct representing a nport
180  */
181 struct spdk_nvmf_fc_nport {
182 
183 	uint16_t nport_hdl;
184 	uint8_t port_hdl;
185 	uint32_t d_id;
186 	enum spdk_nvmf_fc_object_state nport_state;
187 	struct spdk_nvmf_fc_wwn fc_nodename;
188 	struct spdk_nvmf_fc_wwn fc_portname;
189 
190 	/* list of remote ports (i.e. initiators) connected to nport */
191 	TAILQ_HEAD(, spdk_nvmf_fc_remote_port_info) rem_port_list;
192 	uint32_t rport_count;
193 
194 	void *vendor_data;	/* available for vendor use */
195 
196 	/* list of associations to nport */
197 	TAILQ_HEAD(, spdk_nvmf_fc_association) fc_associations;
198 	uint32_t assoc_count;
199 	struct spdk_nvmf_fc_port *fc_port;
200 	TAILQ_ENTRY(spdk_nvmf_fc_nport) link; /* list of nports on a hw port. */
201 };
202 
203 /*
204  * NVMF FC Connection
205  */
206 struct spdk_nvmf_fc_conn {
207 	struct spdk_nvmf_qpair qpair;
208 	struct spdk_nvme_transport_id trid;
209 
210 	uint64_t conn_id;
211 	struct spdk_nvmf_fc_hwqp *hwqp;
212 	uint16_t esrp_ratio;
213 	uint16_t rsp_count;
214 	uint32_t rsn;
215 
216 	/* The maximum number of I/O outstanding on this connection at one time */
217 	uint16_t max_queue_depth;
218 	uint16_t max_rw_depth;
219 	/* The current number of I/O outstanding on this connection. This number
220 	 * includes all I/O from the time the capsule is first received until it is
221 	 * completed.
222 	 */
223 	uint16_t cur_queue_depth;
224 
225 	/* number of read/write requests that are outstanding */
226 	uint16_t cur_fc_rw_depth;
227 
228 	struct spdk_nvmf_fc_association *fc_assoc;
229 
230 	uint16_t rpi;
231 
232 	/* for association's connection list */
233 	TAILQ_ENTRY(spdk_nvmf_fc_conn) assoc_link;
234 
235 	/* for assocations's available connection list */
236 	TAILQ_ENTRY(spdk_nvmf_fc_conn) assoc_avail_link;
237 
238 	/* for hwqp's connection list */
239 	TAILQ_ENTRY(spdk_nvmf_fc_conn) link;
240 
241 	/* New QP create context. */
242 	struct nvmf_fc_ls_op_ctx *create_opd;
243 };
244 
245 /*
246  * Structure for maintaining the FC exchanges
247  */
248 struct spdk_nvmf_fc_xchg {
249 	uint32_t xchg_id;   /* The actual xchg identifier */
250 
251 	/* Internal */
252 	TAILQ_ENTRY(spdk_nvmf_fc_xchg) link;
253 	bool active;
254 	bool aborted;
255 	bool send_abts; /* Valid if is_aborted is set. */
256 };
257 
258 /*
259  *  FC poll group structure
260  */
261 struct spdk_nvmf_fc_poll_group {
262 	struct spdk_nvmf_transport_poll_group group;
263 	struct spdk_nvmf_tgt *nvmf_tgt;
264 	uint32_t hwqp_count; /* number of hwqp's assigned to this pg */
265 	TAILQ_HEAD(, spdk_nvmf_fc_hwqp) hwqp_list;
266 
267 	TAILQ_ENTRY(spdk_nvmf_fc_poll_group) link;
268 };
269 
270 /*
271  *  HWQP poller structure passed from Master thread
272  */
273 struct spdk_nvmf_fc_hwqp {
274 	enum spdk_fc_hwqp_state state;  /* queue state (for poller) */
275 	uint32_t lcore_id;   /* core hwqp is running on (for tracing purposes only) */
276 	struct spdk_thread *thread;  /* thread hwqp is running on */
277 	uint32_t hwqp_id;    /* A unique id (per physical port) for a hwqp */
278 	uint32_t rq_size;    /* receive queue size */
279 	spdk_nvmf_fc_lld_hwqp_t queues;    /* vendor HW queue set */
280 	struct spdk_nvmf_fc_port *fc_port; /* HW port structure for these queues */
281 	struct spdk_nvmf_fc_poll_group *fgroup;
282 
283 	/* qpair (fc_connection) list */
284 	TAILQ_HEAD(, spdk_nvmf_fc_conn) connection_list;
285 	uint32_t num_conns; /* number of connections to queue */
286 
287 	struct spdk_nvmf_fc_request *fc_reqs_buf;
288 	TAILQ_HEAD(, spdk_nvmf_fc_request) free_reqs;
289 	TAILQ_HEAD(, spdk_nvmf_fc_request) in_use_reqs;
290 
291 	struct spdk_nvmf_fc_errors counters;
292 
293 	/* Pending LS request waiting for FC resource */
294 	TAILQ_HEAD(, spdk_nvmf_fc_ls_rqst) ls_pending_queue;
295 
296 	/* Sync req list */
297 	TAILQ_HEAD(, spdk_nvmf_fc_poller_api_queue_sync_args) sync_cbs;
298 
299 	TAILQ_ENTRY(spdk_nvmf_fc_hwqp) link;
300 
301 	void *context;			/* Vendor specific context data */
302 };
303 
304 /*
305  * FC HW port.
306  */
307 struct spdk_nvmf_fc_port {
308 	uint8_t port_hdl;
309 	enum spdk_fc_port_state hw_port_status;
310 	uint16_t fcp_rq_id;
311 	struct spdk_nvmf_fc_hwqp ls_queue;
312 
313 	uint32_t num_io_queues;
314 	struct spdk_nvmf_fc_hwqp *io_queues;
315 	/*
316 	 * List of nports on this HW port.
317 	 */
318 	TAILQ_HEAD(, spdk_nvmf_fc_nport)nport_list;
319 	int	num_nports;
320 	TAILQ_ENTRY(spdk_nvmf_fc_port) link;
321 
322 	struct spdk_mempool *io_resource_pool; /* Pools to store bdev_io's for this port */
323 	void *port_ctx;
324 };
325 
326 /*
327  * NVMF FC Request
328  */
329 struct spdk_nvmf_fc_request {
330 	struct spdk_nvmf_request req;
331 	struct spdk_nvmf_fc_ersp_iu ersp;
332 	uint32_t poller_lcore; /* for tracing purposes only */
333 	struct spdk_thread *poller_thread;
334 	uint16_t buf_index;
335 	struct spdk_nvmf_fc_xchg *xchg;
336 	uint16_t oxid;
337 	uint16_t rpi;
338 	struct spdk_nvmf_fc_conn *fc_conn;
339 	struct spdk_nvmf_fc_hwqp *hwqp;
340 	int state;
341 	uint32_t transfered_len;
342 	bool is_aborted;
343 	uint32_t magic;
344 	uint32_t s_id;
345 	uint32_t d_id;
346 	TAILQ_ENTRY(spdk_nvmf_fc_request) link;
347 	STAILQ_ENTRY(spdk_nvmf_fc_request) pending_link;
348 	TAILQ_HEAD(, spdk_nvmf_fc_caller_ctx) abort_cbs;
349 };
350 
351 SPDK_STATIC_ASSERT(!offsetof(struct spdk_nvmf_fc_request, req),
352 		   "FC request and NVMF request address don't match.");
353 
354 
355 /*
356  * NVMF FC Association
357  */
358 struct spdk_nvmf_fc_association {
359 	uint64_t assoc_id;
360 	uint32_t s_id;
361 	struct spdk_nvmf_fc_nport *tgtport;
362 	struct spdk_nvmf_fc_remote_port_info *rport;
363 	struct spdk_nvmf_subsystem *subsystem;
364 	enum spdk_nvmf_fc_object_state assoc_state;
365 
366 	char host_id[FCNVME_ASSOC_HOSTID_LEN];
367 	char host_nqn[SPDK_NVME_NQN_FIELD_SIZE];
368 	char sub_nqn[SPDK_NVME_NQN_FIELD_SIZE];
369 
370 	struct spdk_nvmf_fc_conn *aq_conn; /* connection for admin queue */
371 
372 	uint16_t conn_count;
373 	TAILQ_HEAD(, spdk_nvmf_fc_conn) fc_conns;
374 
375 	void *conns_buf;
376 	TAILQ_HEAD(, spdk_nvmf_fc_conn) avail_fc_conns;
377 
378 	TAILQ_ENTRY(spdk_nvmf_fc_association) link;
379 
380 	/* for port's association free list */
381 	TAILQ_ENTRY(spdk_nvmf_fc_association) port_free_assoc_list_link;
382 
383 	void *ls_del_op_ctx; /* delete assoc. callback list */
384 
385 	/* disconnect cmd buffers (sent to initiator) */
386 	struct spdk_nvmf_fc_srsr_bufs *snd_disconn_bufs;
387 };
388 
389 /*
390  * FC Remote Port
391  */
392 struct spdk_nvmf_fc_remote_port_info {
393 	uint32_t s_id;
394 	uint32_t rpi;
395 	uint32_t assoc_count;
396 	struct spdk_nvmf_fc_wwn fc_nodename;
397 	struct spdk_nvmf_fc_wwn fc_portname;
398 	enum spdk_nvmf_fc_object_state rport_state;
399 	TAILQ_ENTRY(spdk_nvmf_fc_remote_port_info) link;
400 };
401 
402 /*
403  * Poller API error codes
404  */
405 enum spdk_nvmf_fc_poller_api_ret {
406 	SPDK_NVMF_FC_POLLER_API_SUCCESS = 0,
407 	SPDK_NVMF_FC_POLLER_API_ERROR,
408 	SPDK_NVMF_FC_POLLER_API_INVALID_ARG,
409 	SPDK_NVMF_FC_POLLER_API_NO_CONN_ID,
410 	SPDK_NVMF_FC_POLLER_API_DUP_CONN_ID,
411 	SPDK_NVMF_FC_POLLER_API_OXID_NOT_FOUND,
412 };
413 
414 /*
415  * Poller API definitions
416  */
417 enum spdk_nvmf_fc_poller_api {
418 	SPDK_NVMF_FC_POLLER_API_ADD_CONNECTION,
419 	SPDK_NVMF_FC_POLLER_API_DEL_CONNECTION,
420 	SPDK_NVMF_FC_POLLER_API_QUIESCE_QUEUE,
421 	SPDK_NVMF_FC_POLLER_API_ACTIVATE_QUEUE,
422 	SPDK_NVMF_FC_POLLER_API_ABTS_RECEIVED,
423 	SPDK_NVMF_FC_POLLER_API_REQ_ABORT_COMPLETE,
424 	SPDK_NVMF_FC_POLLER_API_ADAPTER_EVENT,
425 	SPDK_NVMF_FC_POLLER_API_AEN,
426 	SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC,
427 	SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC_DONE,
428 	SPDK_NVMF_FC_POLLER_API_ADD_HWQP,
429 	SPDK_NVMF_FC_POLLER_API_REMOVE_HWQP,
430 };
431 
432 /*
433  * Poller API callback function proto
434  */
435 typedef void (*spdk_nvmf_fc_poller_api_cb)(void *cb_data, enum spdk_nvmf_fc_poller_api_ret ret);
436 
437 /*
438  * Poller API callback data
439  */
440 struct spdk_nvmf_fc_poller_api_cb_info {
441 	struct spdk_thread *cb_thread;
442 	spdk_nvmf_fc_poller_api_cb cb_func;
443 	void *cb_data;
444 	enum spdk_nvmf_fc_poller_api_ret ret;
445 };
446 
447 /*
448  * Poller API structures
449  */
450 struct spdk_nvmf_fc_poller_api_add_connection_args {
451 	struct spdk_nvmf_fc_conn *fc_conn;
452 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
453 };
454 
455 struct spdk_nvmf_fc_poller_api_del_connection_args {
456 	struct spdk_nvmf_fc_conn *fc_conn;
457 	struct spdk_nvmf_fc_hwqp *hwqp;
458 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
459 	bool send_abts;
460 	/* internal */
461 	int fc_request_cnt;
462 	bool backend_initiated;
463 };
464 
465 struct spdk_nvmf_fc_poller_api_quiesce_queue_args {
466 	void   *ctx;
467 	struct spdk_nvmf_fc_hwqp *hwqp;
468 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
469 };
470 
471 struct spdk_nvmf_fc_poller_api_activate_queue_args {
472 	struct spdk_nvmf_fc_hwqp *hwqp;
473 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
474 };
475 
476 struct spdk_nvmf_fc_poller_api_abts_recvd_args {
477 	struct spdk_nvmf_fc_abts_ctx *ctx;
478 	struct spdk_nvmf_fc_hwqp *hwqp;
479 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
480 };
481 
482 struct spdk_nvmf_fc_poller_api_queue_sync_done_args {
483 	struct spdk_nvmf_fc_hwqp *hwqp;
484 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
485 	uint64_t tag;
486 };
487 
488 /*
489  * NVMF LS request structure
490  */
491 struct spdk_nvmf_fc_ls_rqst {
492 	struct spdk_nvmf_fc_buffer_desc rqstbuf;
493 	struct spdk_nvmf_fc_buffer_desc rspbuf;
494 	uint32_t rqst_len;
495 	uint32_t rsp_len;
496 	uint32_t rpi;
497 	struct spdk_nvmf_fc_xchg *xchg;
498 	uint16_t oxid;
499 	void *private_data; /* for LLD only (LS does not touch) */
500 	TAILQ_ENTRY(spdk_nvmf_fc_ls_rqst) ls_pending_link;
501 	uint32_t s_id;
502 	uint32_t d_id;
503 	struct spdk_nvmf_fc_nport *nport;
504 	struct spdk_nvmf_fc_remote_port_info *rport;
505 	struct spdk_nvmf_tgt *nvmf_tgt;
506 };
507 
508 /*
509  * RQ Buffer LS Overlay Structure
510  */
511 #define FCNVME_LS_RSVD_SIZE (FCNVME_MAX_LS_BUFFER_SIZE - \
512 	(sizeof(struct spdk_nvmf_fc_ls_rqst) + FCNVME_MAX_LS_REQ_SIZE + FCNVME_MAX_LS_RSP_SIZE))
513 
514 struct spdk_nvmf_fc_rq_buf_ls_request {
515 	uint8_t rqst[FCNVME_MAX_LS_REQ_SIZE];
516 	uint8_t resp[FCNVME_MAX_LS_RSP_SIZE];
517 	struct spdk_nvmf_fc_ls_rqst ls_rqst;
518 	uint8_t rsvd[FCNVME_LS_RSVD_SIZE];
519 };
520 
521 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fc_rq_buf_ls_request) ==
522 		   FCNVME_MAX_LS_BUFFER_SIZE, "LS RQ Buffer overflow");
523 
524 /* Poller API structures (arguments and callback data */
525 typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
526 
527 struct spdk_nvmf_fc_ls_add_conn_api_data {
528 	struct spdk_nvmf_fc_poller_api_add_connection_args args;
529 	struct spdk_nvmf_fc_ls_rqst *ls_rqst;
530 	struct spdk_nvmf_fc_association *assoc;
531 	bool aq_conn; /* true if adding connection for new association */
532 };
533 
534 /* Disconnect (connection) request functions */
535 struct spdk_nvmf_fc_ls_del_conn_api_data {
536 	struct spdk_nvmf_fc_poller_api_del_connection_args args;
537 	struct spdk_nvmf_fc_ls_rqst *ls_rqst;
538 	struct spdk_nvmf_fc_association *assoc;
539 	bool aq_conn; /* true if deleting AQ connection */
540 };
541 
542 /* used by LS disconnect association cmd handling */
543 struct spdk_nvmf_fc_ls_disconn_assoc_api_data {
544 	struct spdk_nvmf_fc_nport *tgtport;
545 	struct spdk_nvmf_fc_ls_rqst *ls_rqst;
546 };
547 
548 /* used by delete association call */
549 struct spdk_nvmf_fc_delete_assoc_api_data {
550 	struct spdk_nvmf_fc_poller_api_del_connection_args args;
551 	struct spdk_nvmf_fc_association *assoc;
552 	bool from_ls_rqst;   /* true = request came for LS */
553 	spdk_nvmf_fc_del_assoc_cb del_assoc_cb;
554 	void *del_assoc_cb_data;
555 };
556 
557 struct nvmf_fc_ls_op_ctx {
558 	union {
559 		struct spdk_nvmf_fc_ls_add_conn_api_data add_conn;
560 		struct spdk_nvmf_fc_ls_del_conn_api_data del_conn;
561 		struct spdk_nvmf_fc_ls_disconn_assoc_api_data disconn_assoc;
562 		struct spdk_nvmf_fc_delete_assoc_api_data del_assoc;
563 	} u;
564 	struct  nvmf_fc_ls_op_ctx *next_op_ctx;
565 };
566 
567 struct spdk_nvmf_fc_poller_api_queue_sync_args {
568 	uint64_t u_id;
569 	struct spdk_nvmf_fc_hwqp *hwqp;
570 	struct spdk_nvmf_fc_poller_api_cb_info cb_info;
571 
572 	/* Used internally by poller */
573 	TAILQ_ENTRY(spdk_nvmf_fc_poller_api_queue_sync_args) link;
574 };
575 
576 /**
577  * Following defines and structures are used to pass messages between master thread
578  * and FCT driver.
579  */
580 enum spdk_fc_event {
581 	SPDK_FC_HW_PORT_INIT,
582 	SPDK_FC_HW_PORT_ONLINE,
583 	SPDK_FC_HW_PORT_OFFLINE,
584 	SPDK_FC_HW_PORT_RESET,
585 	SPDK_FC_NPORT_CREATE,
586 	SPDK_FC_NPORT_DELETE,
587 	SPDK_FC_IT_ADD,    /* PRLI */
588 	SPDK_FC_IT_DELETE, /* PRLI */
589 	SPDK_FC_ABTS_RECV,
590 	SPDK_FC_LINK_BREAK,
591 	SPDK_FC_HW_PORT_DUMP,
592 	SPDK_FC_UNRECOVERABLE_ERR,
593 	SPDK_FC_EVENT_MAX,
594 };
595 
596 /**
597  * Arguments for to dump assoc id
598  */
599 struct spdk_nvmf_fc_dump_assoc_id_args {
600 	uint8_t                           pport_handle;
601 	uint16_t                          nport_handle;
602 	uint32_t                          assoc_id;
603 };
604 
605 /**
606  * Arguments for HW port init event.
607  */
608 struct spdk_nvmf_fc_hw_port_init_args {
609 	uint32_t                       ls_queue_size;
610 	spdk_nvmf_fc_lld_hwqp_t        ls_queue;
611 	uint32_t                       io_queue_size;
612 	uint32_t                       io_queue_cnt;
613 	spdk_nvmf_fc_lld_hwqp_t       *io_queues;
614 	void                          *cb_ctx;
615 	void                          *port_ctx;
616 	uint8_t                        port_handle;
617 	uint8_t                        nvme_aq_index;  /* io_queue used for nvme admin queue */
618 	uint16_t                       fcp_rq_id; /* Base rq ID of SCSI queue */
619 };
620 
621 /**
622  * Arguments for HW port link break event.
623  */
624 struct spdk_nvmf_hw_port_link_break_args {
625 	uint8_t port_handle;
626 	void   *cb_ctx;
627 };
628 
629 /**
630  * Arguments for HW port online event.
631  */
632 struct spdk_nvmf_fc_hw_port_online_args {
633 	uint8_t port_handle;
634 	void   *cb_ctx;
635 };
636 
637 /**
638  * Arguments for HW port offline event.
639  */
640 struct spdk_nvmf_fc_hw_port_offline_args {
641 	uint8_t port_handle;
642 	void   *cb_ctx;
643 };
644 
645 /**
646  * Arguments for n-port add event.
647  */
648 struct spdk_nvmf_fc_nport_create_args {
649 	uint8_t                     port_handle;
650 	uint16_t                    nport_handle;
651 	struct spdk_uuid            container_uuid; /* UUID of the nports container */
652 	struct spdk_uuid            nport_uuid;     /* Unique UUID for the nport */
653 	uint32_t                    d_id;
654 	struct spdk_nvmf_fc_wwn fc_nodename;
655 	struct spdk_nvmf_fc_wwn fc_portname;
656 	uint32_t                    subsys_id; /* Subsystemid */
657 	char                        port_id[SPDK_NVMF_PORT_ID_MAX_LEN];
658 	void                       *cb_ctx;
659 };
660 
661 /**
662  * Arguments for n-port delete event.
663  */
664 struct spdk_nvmf_fc_nport_delete_args {
665 	uint8_t  port_handle;
666 	uint32_t nport_handle;
667 	uint32_t subsys_id; /* Subsystem id */
668 	void    *cb_ctx;
669 };
670 
671 /**
672  * Arguments for I_T add event.
673  */
674 struct spdk_nvmf_fc_hw_i_t_add_args {
675 	uint8_t                      port_handle;
676 	uint32_t                     nport_handle;
677 	uint16_t                     itn_handle;
678 	uint32_t                     rpi;
679 	uint32_t                     s_id;
680 	uint32_t                     initiator_prli_info;
681 	uint32_t                     target_prli_info; /* populated by the SPDK master */
682 	struct spdk_nvmf_fc_wwn  fc_nodename;
683 	struct spdk_nvmf_fc_wwn  fc_portname;
684 	void                        *cb_ctx;
685 };
686 
687 /**
688  * Arguments for I_T delete event.
689  */
690 struct spdk_nvmf_fc_hw_i_t_delete_args {
691 	uint8_t  port_handle;
692 	uint32_t nport_handle;
693 	uint16_t itn_handle;    /* Only used by FC LLD driver; unused in SPDK */
694 	uint32_t rpi;
695 	uint32_t s_id;
696 	void    *cb_ctx;
697 };
698 
699 /**
700  * Arguments for ABTS  event.
701  */
702 struct spdk_nvmf_fc_abts_args {
703 	uint8_t  port_handle;
704 	uint32_t nport_handle;
705 	uint32_t rpi;
706 	uint16_t oxid, rxid;
707 	void    *cb_ctx;
708 };
709 
710 /**
711  * Arguments for link break event.
712  */
713 struct spdk_nvmf_fc_link_break_args {
714 	uint8_t port_handle;
715 };
716 
717 /**
718  * Arguments for port reset event.
719  */
720 struct spdk_nvmf_fc_hw_port_reset_args {
721 	uint8_t    port_handle;
722 	bool       dump_queues;
723 	char       reason[SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE];
724 	uint32_t **dump_buf;
725 	void      *cb_ctx;
726 };
727 
728 /**
729  * Arguments for unrecoverable error event
730  */
731 struct spdk_nvmf_fc_unrecoverable_error_event_args {
732 };
733 
734 /**
735  * Callback function to the FCT driver.
736  */
737 typedef void (*spdk_nvmf_fc_callback)(uint8_t port_handle,
738 				      enum spdk_fc_event event_type,
739 				      void *arg, int err);
740 
741 /**
742  * Enqueue an FCT event to master thread
743  *
744  * \param event_type Type of the event.
745  * \param args Pointer to the argument structure.
746  * \param cb_func Callback function into fc driver.
747  *
748  * \return 0 on success, non-zero on failure.
749  */
750 int
751 nvmf_fc_master_enqueue_event(enum spdk_fc_event event_type,
752 			     void *args,
753 			     spdk_nvmf_fc_callback cb_func);
754 
755 /*
756  * dump info
757  */
758 struct spdk_nvmf_fc_queue_dump_info {
759 	char *buffer;
760 	int   offset;
761 };
762 #define SPDK_FC_HW_DUMP_BUF_SIZE (10 * 4096)
763 
764 static inline void
765 nvmf_fc_dump_buf_print(struct spdk_nvmf_fc_queue_dump_info *dump_info, char *fmt, ...)
766 {
767 	uint64_t buffer_size = SPDK_FC_HW_DUMP_BUF_SIZE;
768 	int32_t avail = (int32_t)(buffer_size - dump_info->offset);
769 
770 	if (avail > 0) {
771 		va_list ap;
772 		int32_t written;
773 
774 		va_start(ap, fmt);
775 		written = vsnprintf(dump_info->buffer + dump_info->offset, avail, fmt, ap);
776 		if (written >= avail) {
777 			dump_info->offset += avail;
778 		} else {
779 			dump_info->offset += written;
780 		}
781 		va_end(ap);
782 	}
783 }
784 
785 /*
786  * NVMF FC caller callback definitions
787  */
788 typedef void (*spdk_nvmf_fc_caller_cb)(void *hwqp, int32_t status, void *args);
789 
790 struct spdk_nvmf_fc_caller_ctx {
791 	void *ctx;
792 	spdk_nvmf_fc_caller_cb cb;
793 	void *cb_args;
794 	TAILQ_ENTRY(spdk_nvmf_fc_caller_ctx) link;
795 };
796 
797 /*
798  * NVMF FC Exchange Info (for debug)
799  */
800 struct spdk_nvmf_fc_xchg_info {
801 	uint32_t xchg_base;
802 	uint32_t xchg_total_count;
803 	uint32_t xchg_avail_count;
804 	uint32_t send_frame_xchg_id;
805 	uint8_t send_frame_seqid;
806 };
807 
808 /*
809  * NVMF FC inline and function prototypes
810  */
811 
812 static inline struct spdk_nvmf_fc_request *
813 nvmf_fc_get_fc_req(struct spdk_nvmf_request *req)
814 {
815 	return (struct spdk_nvmf_fc_request *)
816 	       ((uintptr_t)req - offsetof(struct spdk_nvmf_fc_request, req));
817 }
818 
819 static inline bool
820 nvmf_fc_is_port_dead(struct spdk_nvmf_fc_hwqp *hwqp)
821 {
822 	switch (hwqp->fc_port->hw_port_status) {
823 	case SPDK_FC_PORT_QUIESCED:
824 		return true;
825 	default:
826 		return false;
827 	}
828 }
829 
830 static inline bool
831 nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
832 {
833 	switch (fc_req->state) {
834 	case SPDK_NVMF_FC_REQ_READ_XFER:
835 	case SPDK_NVMF_FC_REQ_READ_RSP:
836 	case SPDK_NVMF_FC_REQ_WRITE_XFER:
837 	case SPDK_NVMF_FC_REQ_WRITE_RSP:
838 	case SPDK_NVMF_FC_REQ_NONE_RSP:
839 		return true;
840 	default:
841 		return false;
842 	}
843 }
844 
845 static inline void
846 nvmf_fc_create_trid(struct spdk_nvme_transport_id *trid, uint64_t n_wwn, uint64_t p_wwn)
847 {
848 	spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_FC);
849 	trid->adrfam = SPDK_NVMF_ADRFAM_FC;
850 	snprintf(trid->trsvcid, sizeof(trid->trsvcid), "none");
851 	snprintf(trid->traddr, sizeof(trid->traddr), "nn-0x%lx:pn-0x%lx", n_wwn, p_wwn);
852 }
853 
854 void nvmf_fc_ls_init(struct spdk_nvmf_fc_port *fc_port);
855 
856 void nvmf_fc_ls_fini(struct spdk_nvmf_fc_port *fc_port);
857 
858 void nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst);
859 void nvmf_fc_ls_add_conn_failure(
860 	struct spdk_nvmf_fc_association *assoc,
861 	struct spdk_nvmf_fc_ls_rqst *ls_rqst,
862 	struct spdk_nvmf_fc_conn *fc_conn,
863 	bool aq_conn);
864 
865 void nvmf_fc_init_hwqp(struct spdk_nvmf_fc_port *fc_port, struct spdk_nvmf_fc_hwqp *hwqp);
866 
867 void nvmf_fc_init_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp);
868 
869 struct spdk_nvmf_fc_conn *nvmf_fc_hwqp_find_fc_conn(struct spdk_nvmf_fc_hwqp *hwqp,
870 		uint64_t conn_id);
871 
872 void nvmf_fc_hwqp_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp, void *queues_curr);
873 
874 struct spdk_nvmf_fc_port *nvmf_fc_port_lookup(uint8_t port_hdl);
875 
876 bool nvmf_fc_port_is_offline(struct spdk_nvmf_fc_port *fc_port);
877 
878 int nvmf_fc_port_set_offline(struct spdk_nvmf_fc_port *fc_port);
879 
880 bool nvmf_fc_port_is_online(struct spdk_nvmf_fc_port *fc_port);
881 
882 int nvmf_fc_port_set_online(struct spdk_nvmf_fc_port *fc_port);
883 
884 int nvmf_fc_rport_set_state(struct spdk_nvmf_fc_remote_port_info *rport,
885 			    enum spdk_nvmf_fc_object_state state);
886 
887 void nvmf_fc_port_add(struct spdk_nvmf_fc_port *fc_port);
888 
889 int nvmf_fc_port_add_nport(struct spdk_nvmf_fc_port *fc_port,
890 			   struct spdk_nvmf_fc_nport *nport);
891 
892 int nvmf_fc_port_remove_nport(struct spdk_nvmf_fc_port *fc_port,
893 			      struct spdk_nvmf_fc_nport *nport);
894 
895 struct spdk_nvmf_fc_nport *nvmf_fc_nport_find(uint8_t port_hdl, uint16_t nport_hdl);
896 
897 int nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport,
898 			    enum spdk_nvmf_fc_object_state state);
899 
900 bool nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport,
901 				struct spdk_nvmf_fc_remote_port_info *rem_port);
902 
903 bool nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport,
904 				   struct spdk_nvmf_fc_remote_port_info *rem_port);
905 
906 bool nvmf_fc_nport_has_no_rport(struct spdk_nvmf_fc_nport *nport);
907 
908 int nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc,
909 			    enum spdk_nvmf_fc_object_state state);
910 
911 int nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
912 			       uint64_t assoc_id, bool send_abts, bool backend_initiated,
913 			       spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
914 			       void *cb_data);
915 
916 bool nvmf_ctrlr_is_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
917 			    struct spdk_nvmf_ctrlr *ctrlr);
918 
919 void nvmf_fc_assign_queue_to_master_thread(struct spdk_nvmf_fc_hwqp *hwqp);
920 
921 void nvmf_fc_poll_group_add_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
922 
923 void nvmf_fc_poll_group_remove_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
924 
925 int nvmf_fc_hwqp_set_online(struct spdk_nvmf_fc_hwqp *hwqp);
926 
927 int nvmf_fc_hwqp_set_offline(struct spdk_nvmf_fc_hwqp *hwqp);
928 
929 uint32_t nvmf_fc_get_prli_service_params(void);
930 
931 void nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport, uint16_t rpi, uint16_t oxid,
932 			       uint16_t rxid);
933 
934 void nvmf_fc_request_abort(struct spdk_nvmf_fc_request *fc_req, bool send_abts,
935 			   spdk_nvmf_fc_caller_cb cb, void *cb_args);
936 
937 struct spdk_nvmf_tgt *nvmf_fc_get_tgt(void);
938 
939 struct spdk_thread *nvmf_fc_get_master_thread(void);
940 
941 /*
942  * These functions are called by low level FC driver
943  */
944 
945 static inline struct spdk_nvmf_fc_conn *
946 nvmf_fc_get_conn(struct spdk_nvmf_qpair *qpair)
947 {
948 	return (struct spdk_nvmf_fc_conn *)
949 	       ((uintptr_t)qpair - offsetof(struct spdk_nvmf_fc_conn, qpair));
950 }
951 
952 static inline uint16_t
953 nvmf_fc_advance_conn_sqhead(struct spdk_nvmf_qpair *qpair)
954 {
955 	/* advance sq_head pointer - wrap if needed */
956 	qpair->sq_head = (qpair->sq_head == qpair->sq_head_max) ?
957 			 0 : (qpair->sq_head + 1);
958 	return qpair->sq_head;
959 }
960 
961 static inline bool
962 nvmf_fc_use_send_frame(struct spdk_nvmf_request *req)
963 {
964 	/* For now use for only keepalives. */
965 	if (req->qpair->qid == 0 &&
966 	    (req->cmd->nvme_cmd.opc == SPDK_NVME_OPC_KEEP_ALIVE)) {
967 		return true;
968 	}
969 	return false;
970 }
971 
972 enum spdk_nvmf_fc_poller_api_ret nvmf_fc_poller_api_func(
973 	struct spdk_nvmf_fc_hwqp *hwqp,
974 	enum spdk_nvmf_fc_poller_api api,
975 	void *api_args);
976 
977 int nvmf_fc_hwqp_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx,
978 			       struct spdk_nvmf_fc_frame_hdr *frame,
979 			       struct spdk_nvmf_fc_buffer_desc *buffer, uint32_t plen);
980 
981 void nvmf_fc_hwqp_process_pending_reqs(struct spdk_nvmf_fc_hwqp *hwqp);
982 
983 void nvmf_fc_hwqp_process_pending_ls_rqsts(struct spdk_nvmf_fc_hwqp *hwqp);
984 
985 void nvmf_fc_request_set_state(struct spdk_nvmf_fc_request *fc_req,
986 			       enum spdk_nvmf_fc_request_state state);
987 
988 char *nvmf_fc_request_get_state_str(int state);
989 
990 void _nvmf_fc_request_free(struct spdk_nvmf_fc_request *fc_req);
991 
992 void nvmf_fc_request_abort_complete(void *arg1);
993 
994 bool nvmf_fc_send_ersp_required(struct spdk_nvmf_fc_request *fc_req,
995 				uint32_t rsp_cnt, uint32_t xfer_len);
996 
997 int nvmf_fc_handle_rsp(struct spdk_nvmf_fc_request *req);
998 
999 #endif
1000