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