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