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