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