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_HW_PORT_DUMP, 591 SPDK_FC_UNRECOVERABLE_ERR, 592 SPDK_FC_EVENT_MAX, 593 }; 594 595 /** 596 * Arguments for to dump assoc id 597 */ 598 struct spdk_nvmf_fc_dump_assoc_id_args { 599 uint8_t pport_handle; 600 uint16_t nport_handle; 601 uint32_t assoc_id; 602 }; 603 604 /** 605 * Arguments for HW port init event. 606 */ 607 struct spdk_nvmf_fc_hw_port_init_args { 608 uint32_t ls_queue_size; 609 spdk_nvmf_fc_lld_hwqp_t ls_queue; 610 uint32_t io_queue_size; 611 uint32_t io_queue_cnt; 612 spdk_nvmf_fc_lld_hwqp_t *io_queues; 613 void *cb_ctx; 614 void *port_ctx; 615 uint8_t port_handle; 616 uint8_t nvme_aq_index; /* io_queue used for nvme admin queue */ 617 uint16_t fcp_rq_id; /* Base rq ID of SCSI queue */ 618 }; 619 620 /** 621 * Arguments for HW port online event. 622 */ 623 struct spdk_nvmf_fc_hw_port_online_args { 624 uint8_t port_handle; 625 void *cb_ctx; 626 }; 627 628 /** 629 * Arguments for HW port offline event. 630 */ 631 struct spdk_nvmf_fc_hw_port_offline_args { 632 uint8_t port_handle; 633 void *cb_ctx; 634 }; 635 636 /** 637 * Arguments for n-port add event. 638 */ 639 struct spdk_nvmf_fc_nport_create_args { 640 uint8_t port_handle; 641 uint16_t nport_handle; 642 struct spdk_uuid container_uuid; /* UUID of the nports container */ 643 struct spdk_uuid nport_uuid; /* Unique UUID for the nport */ 644 uint32_t d_id; 645 struct spdk_nvmf_fc_wwn fc_nodename; 646 struct spdk_nvmf_fc_wwn fc_portname; 647 uint32_t subsys_id; /* Subsystemid */ 648 char port_id[SPDK_NVMF_PORT_ID_MAX_LEN]; 649 void *cb_ctx; 650 }; 651 652 /** 653 * Arguments for n-port delete event. 654 */ 655 struct spdk_nvmf_fc_nport_delete_args { 656 uint8_t port_handle; 657 uint32_t nport_handle; 658 uint32_t subsys_id; /* Subsystem id */ 659 void *cb_ctx; 660 }; 661 662 /** 663 * Arguments for I_T add event. 664 */ 665 struct spdk_nvmf_fc_hw_i_t_add_args { 666 uint8_t port_handle; 667 uint32_t nport_handle; 668 uint16_t itn_handle; 669 uint32_t rpi; 670 uint32_t s_id; 671 uint32_t initiator_prli_info; 672 uint32_t target_prli_info; /* populated by the SPDK master */ 673 struct spdk_nvmf_fc_wwn fc_nodename; 674 struct spdk_nvmf_fc_wwn fc_portname; 675 void *cb_ctx; 676 }; 677 678 /** 679 * Arguments for I_T delete event. 680 */ 681 struct spdk_nvmf_fc_hw_i_t_delete_args { 682 uint8_t port_handle; 683 uint32_t nport_handle; 684 uint16_t itn_handle; /* Only used by FC LLD driver; unused in SPDK */ 685 uint32_t rpi; 686 uint32_t s_id; 687 void *cb_ctx; 688 }; 689 690 /** 691 * Arguments for ABTS event. 692 */ 693 struct spdk_nvmf_fc_abts_args { 694 uint8_t port_handle; 695 uint32_t nport_handle; 696 uint32_t rpi; 697 uint16_t oxid, rxid; 698 void *cb_ctx; 699 }; 700 701 /** 702 * Arguments for port reset event. 703 */ 704 struct spdk_nvmf_fc_hw_port_reset_args { 705 uint8_t port_handle; 706 bool dump_queues; 707 char reason[SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE]; 708 uint32_t **dump_buf; 709 void *cb_ctx; 710 }; 711 712 /** 713 * Arguments for unrecoverable error event 714 */ 715 struct spdk_nvmf_fc_unrecoverable_error_event_args { 716 }; 717 718 /** 719 * Callback function to the FCT driver. 720 */ 721 typedef void (*spdk_nvmf_fc_callback)(uint8_t port_handle, 722 enum spdk_fc_event event_type, 723 void *arg, int err); 724 725 /** 726 * Enqueue an FCT event to master thread 727 * 728 * \param event_type Type of the event. 729 * \param args Pointer to the argument structure. 730 * \param cb_func Callback function into fc driver. 731 * 732 * \return 0 on success, non-zero on failure. 733 */ 734 int 735 nvmf_fc_master_enqueue_event(enum spdk_fc_event event_type, 736 void *args, 737 spdk_nvmf_fc_callback cb_func); 738 739 /* 740 * dump info 741 */ 742 struct spdk_nvmf_fc_queue_dump_info { 743 char *buffer; 744 int offset; 745 }; 746 #define SPDK_FC_HW_DUMP_BUF_SIZE (10 * 4096) 747 748 static inline void 749 nvmf_fc_dump_buf_print(struct spdk_nvmf_fc_queue_dump_info *dump_info, char *fmt, ...) 750 { 751 uint64_t buffer_size = SPDK_FC_HW_DUMP_BUF_SIZE; 752 int32_t avail = (int32_t)(buffer_size - dump_info->offset); 753 754 if (avail > 0) { 755 va_list ap; 756 int32_t written; 757 758 va_start(ap, fmt); 759 written = vsnprintf(dump_info->buffer + dump_info->offset, avail, fmt, ap); 760 if (written >= avail) { 761 dump_info->offset += avail; 762 } else { 763 dump_info->offset += written; 764 } 765 va_end(ap); 766 } 767 } 768 769 /* 770 * NVMF FC caller callback definitions 771 */ 772 typedef void (*spdk_nvmf_fc_caller_cb)(void *hwqp, int32_t status, void *args); 773 774 struct spdk_nvmf_fc_caller_ctx { 775 void *ctx; 776 spdk_nvmf_fc_caller_cb cb; 777 void *cb_args; 778 TAILQ_ENTRY(spdk_nvmf_fc_caller_ctx) link; 779 }; 780 781 /* 782 * NVMF FC Exchange Info (for debug) 783 */ 784 struct spdk_nvmf_fc_xchg_info { 785 uint32_t xchg_base; 786 uint32_t xchg_total_count; 787 uint32_t xchg_avail_count; 788 uint32_t send_frame_xchg_id; 789 uint8_t send_frame_seqid; 790 }; 791 792 /* 793 * NVMF FC inline and function prototypes 794 */ 795 796 static inline struct spdk_nvmf_fc_request * 797 nvmf_fc_get_fc_req(struct spdk_nvmf_request *req) 798 { 799 return (struct spdk_nvmf_fc_request *) 800 ((uintptr_t)req - offsetof(struct spdk_nvmf_fc_request, req)); 801 } 802 803 static inline bool 804 nvmf_fc_is_port_dead(struct spdk_nvmf_fc_hwqp *hwqp) 805 { 806 switch (hwqp->fc_port->hw_port_status) { 807 case SPDK_FC_PORT_QUIESCED: 808 return true; 809 default: 810 return false; 811 } 812 } 813 814 static inline bool 815 nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req) 816 { 817 switch (fc_req->state) { 818 case SPDK_NVMF_FC_REQ_READ_XFER: 819 case SPDK_NVMF_FC_REQ_READ_RSP: 820 case SPDK_NVMF_FC_REQ_WRITE_XFER: 821 case SPDK_NVMF_FC_REQ_WRITE_RSP: 822 case SPDK_NVMF_FC_REQ_NONE_RSP: 823 return true; 824 default: 825 return false; 826 } 827 } 828 829 static inline void 830 nvmf_fc_create_trid(struct spdk_nvme_transport_id *trid, uint64_t n_wwn, uint64_t p_wwn) 831 { 832 spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_FC); 833 trid->adrfam = SPDK_NVMF_ADRFAM_FC; 834 snprintf(trid->trsvcid, sizeof(trid->trsvcid), "none"); 835 snprintf(trid->traddr, sizeof(trid->traddr), "nn-0x%lx:pn-0x%lx", n_wwn, p_wwn); 836 } 837 838 void nvmf_fc_ls_init(struct spdk_nvmf_fc_port *fc_port); 839 840 void nvmf_fc_ls_fini(struct spdk_nvmf_fc_port *fc_port); 841 842 void nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst); 843 void nvmf_fc_ls_add_conn_failure( 844 struct spdk_nvmf_fc_association *assoc, 845 struct spdk_nvmf_fc_ls_rqst *ls_rqst, 846 struct spdk_nvmf_fc_conn *fc_conn, 847 bool aq_conn); 848 849 void nvmf_fc_init_hwqp(struct spdk_nvmf_fc_port *fc_port, struct spdk_nvmf_fc_hwqp *hwqp); 850 851 void nvmf_fc_init_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp); 852 853 struct spdk_nvmf_fc_conn *nvmf_fc_hwqp_find_fc_conn(struct spdk_nvmf_fc_hwqp *hwqp, 854 uint64_t conn_id); 855 856 void nvmf_fc_hwqp_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp, void *queues_curr); 857 858 struct spdk_nvmf_fc_port *nvmf_fc_port_lookup(uint8_t port_hdl); 859 860 bool nvmf_fc_port_is_offline(struct spdk_nvmf_fc_port *fc_port); 861 862 int nvmf_fc_port_set_offline(struct spdk_nvmf_fc_port *fc_port); 863 864 bool nvmf_fc_port_is_online(struct spdk_nvmf_fc_port *fc_port); 865 866 int nvmf_fc_port_set_online(struct spdk_nvmf_fc_port *fc_port); 867 868 int nvmf_fc_rport_set_state(struct spdk_nvmf_fc_remote_port_info *rport, 869 enum spdk_nvmf_fc_object_state state); 870 871 void nvmf_fc_port_add(struct spdk_nvmf_fc_port *fc_port); 872 873 int nvmf_fc_port_add_nport(struct spdk_nvmf_fc_port *fc_port, 874 struct spdk_nvmf_fc_nport *nport); 875 876 int nvmf_fc_port_remove_nport(struct spdk_nvmf_fc_port *fc_port, 877 struct spdk_nvmf_fc_nport *nport); 878 879 struct spdk_nvmf_fc_nport *nvmf_fc_nport_find(uint8_t port_hdl, uint16_t nport_hdl); 880 881 int nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport, 882 enum spdk_nvmf_fc_object_state state); 883 884 bool nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport, 885 struct spdk_nvmf_fc_remote_port_info *rem_port); 886 887 bool nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport, 888 struct spdk_nvmf_fc_remote_port_info *rem_port); 889 890 bool nvmf_fc_nport_has_no_rport(struct spdk_nvmf_fc_nport *nport); 891 892 int nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc, 893 enum spdk_nvmf_fc_object_state state); 894 895 int nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport, 896 uint64_t assoc_id, bool send_abts, bool backend_initiated, 897 spdk_nvmf_fc_del_assoc_cb del_assoc_cb, 898 void *cb_data); 899 900 bool nvmf_ctrlr_is_on_nport(uint8_t port_hdl, uint16_t nport_hdl, 901 struct spdk_nvmf_ctrlr *ctrlr); 902 903 void nvmf_fc_assign_queue_to_master_thread(struct spdk_nvmf_fc_hwqp *hwqp); 904 905 void nvmf_fc_poll_group_add_hwqp(struct spdk_nvmf_fc_hwqp *hwqp); 906 907 void nvmf_fc_poll_group_remove_hwqp(struct spdk_nvmf_fc_hwqp *hwqp); 908 909 int nvmf_fc_hwqp_set_online(struct spdk_nvmf_fc_hwqp *hwqp); 910 911 int nvmf_fc_hwqp_set_offline(struct spdk_nvmf_fc_hwqp *hwqp); 912 913 uint32_t nvmf_fc_get_prli_service_params(void); 914 915 void nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport, uint16_t rpi, uint16_t oxid, 916 uint16_t rxid); 917 918 void nvmf_fc_request_abort(struct spdk_nvmf_fc_request *fc_req, bool send_abts, 919 spdk_nvmf_fc_caller_cb cb, void *cb_args); 920 921 struct spdk_nvmf_tgt *nvmf_fc_get_tgt(void); 922 923 struct spdk_thread *nvmf_fc_get_master_thread(void); 924 925 /* 926 * These functions are called by low level FC driver 927 */ 928 929 static inline struct spdk_nvmf_fc_conn * 930 nvmf_fc_get_conn(struct spdk_nvmf_qpair *qpair) 931 { 932 return (struct spdk_nvmf_fc_conn *) 933 ((uintptr_t)qpair - offsetof(struct spdk_nvmf_fc_conn, qpair)); 934 } 935 936 static inline uint16_t 937 nvmf_fc_advance_conn_sqhead(struct spdk_nvmf_qpair *qpair) 938 { 939 /* advance sq_head pointer - wrap if needed */ 940 qpair->sq_head = (qpair->sq_head == qpair->sq_head_max) ? 941 0 : (qpair->sq_head + 1); 942 return qpair->sq_head; 943 } 944 945 static inline bool 946 nvmf_fc_use_send_frame(struct spdk_nvmf_request *req) 947 { 948 /* For now use for only keepalives. */ 949 if (req->qpair->qid == 0 && 950 (req->cmd->nvme_cmd.opc == SPDK_NVME_OPC_KEEP_ALIVE)) { 951 return true; 952 } 953 return false; 954 } 955 956 enum spdk_nvmf_fc_poller_api_ret nvmf_fc_poller_api_func( 957 struct spdk_nvmf_fc_hwqp *hwqp, 958 enum spdk_nvmf_fc_poller_api api, 959 void *api_args); 960 961 int nvmf_fc_hwqp_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx, 962 struct spdk_nvmf_fc_frame_hdr *frame, 963 struct spdk_nvmf_fc_buffer_desc *buffer, uint32_t plen); 964 965 void nvmf_fc_hwqp_process_pending_reqs(struct spdk_nvmf_fc_hwqp *hwqp); 966 967 void nvmf_fc_hwqp_process_pending_ls_rqsts(struct spdk_nvmf_fc_hwqp *hwqp); 968 969 void nvmf_fc_request_set_state(struct spdk_nvmf_fc_request *fc_req, 970 enum spdk_nvmf_fc_request_state state); 971 972 char *nvmf_fc_request_get_state_str(int state); 973 974 void _nvmf_fc_request_free(struct spdk_nvmf_fc_request *fc_req); 975 976 void nvmf_fc_request_abort_complete(void *arg1); 977 978 bool nvmf_fc_send_ersp_required(struct spdk_nvmf_fc_request *fc_req, 979 uint32_t rsp_cnt, uint32_t xfer_len); 980 981 int nvmf_fc_handle_rsp(struct spdk_nvmf_fc_request *req); 982 983 #endif 984