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