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