]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/spdk/lib/nvmf/nvmf_fc.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / lib / nvmf / nvmf_fc.h
index bf0868311b8215a7fb47d224e472614460ebe0cf..10d3ef9cf559c628e0d23734dce721c62bf688e8 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   BSD LICENSE
  *
- *   Copyright (c) 2018 Broadcom.  All Rights Reserved.
+ *   Copyright (c) 2018-2019 Broadcom.  All Rights Reserved.
  *   The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
  *
  *   Redistribution and use in source and binary forms, with or without
 #ifndef __NVMF_FC_H__
 #define __NVMF_FC_H__
 
+#include "spdk/nvme.h"
 #include "spdk/nvmf.h"
 #include "spdk/assert.h"
 #include "spdk/nvme_spec.h"
 #include "spdk/nvmf_fc_spec.h"
-#include "spdk/event.h"
-#include "spdk/io_channel.h"
+#include "spdk/thread.h"
 #include "nvmf_internal.h"
 
 #define SPDK_NVMF_FC_TR_ADDR_LEN 64
+#define NVMF_FC_INVALID_CONN_ID UINT64_MAX
+
+#define SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE 256
+#define SPDK_MAX_NUM_OF_FC_PORTS 32
+#define SPDK_NVMF_PORT_ID_MAX_LEN 32
+
+/*
+ * FC HWQP pointer
+ */
+typedef void *spdk_nvmf_fc_lld_hwqp_t;
 
 /*
  * FC HW port states.
@@ -59,7 +69,7 @@ enum spdk_fc_hwqp_state {
 };
 
 /*
- * NVMF BCM FC Object state
+ * NVMF FC Object state
  * Add all the generic states of the object here.
  * Specific object states can be added separately
  */
@@ -86,25 +96,11 @@ enum spdk_nvmf_fc_request_state {
        SPDK_NVMF_FC_REQ_SUCCESS,
        SPDK_NVMF_FC_REQ_FAILED,
        SPDK_NVMF_FC_REQ_ABORTED,
+       SPDK_NVMF_FC_REQ_BDEV_ABORTED,
        SPDK_NVMF_FC_REQ_PENDING,
        SPDK_NVMF_FC_REQ_MAX_STATE,
 };
 
-/*
- * FC HWQP pointer
- */
-typedef void *spdk_nvmf_fc_lld_hwqp_t;
-
-/*
- * FC World Wide Name
- */
-struct spdk_nvmf_fc_wwn {
-       union {
-               uint64_t wwn; /* World Wide Names consist of eight bytes */
-               uint8_t octets[sizeof(uint64_t)];
-       } u;
-};
-
 /*
  * Generic DMA buffer descriptor
  */
@@ -142,7 +138,7 @@ struct spdk_nvmf_fc_abts_ctx {
  * NVME FC transport errors
  */
 struct spdk_nvmf_fc_errors {
-       uint32_t no_xri;
+       uint32_t no_xchg;
        uint32_t nport_invalid;
        uint32_t unknown_frame;
        uint32_t wqe_cmplt_err;
@@ -154,9 +150,7 @@ struct spdk_nvmf_fc_errors {
        uint32_t invalid_cq_type;
        uint32_t invalid_cq_id;
        uint32_t fc_req_buf_err;
-       uint32_t aq_buf_alloc_err;
-       uint32_t write_buf_alloc_err;
-       uint32_t read_buf_alloc_err;
+       uint32_t buf_alloc_err;
        uint32_t unexpected_err;
        uint32_t nvme_cmd_iu_err;
        uint32_t nvme_cmd_xfer_err;
@@ -173,10 +167,11 @@ struct spdk_nvmf_fc_errors {
 /*
  *  Send Single Request/Response Sequence.
  */
-struct spdk_nvmf_fc_send_srsr {
-       struct spdk_nvmf_fc_buffer_desc rqst;
-       struct spdk_nvmf_fc_buffer_desc rsp;
-       struct spdk_nvmf_fc_buffer_desc sgl; /* Note: Len = (2 * bcm_sge_t) */
+struct spdk_nvmf_fc_srsr_bufs {
+       void *rqst;
+       size_t rqst_len;
+       void *rsp;
+       size_t rsp_len;
        uint16_t rpi;
 };
 
@@ -210,6 +205,7 @@ struct spdk_nvmf_fc_nport {
  */
 struct spdk_nvmf_fc_conn {
        struct spdk_nvmf_qpair qpair;
+       struct spdk_nvme_transport_id trid;
 
        uint64_t conn_id;
        struct spdk_nvmf_fc_hwqp *hwqp;
@@ -229,12 +225,8 @@ struct spdk_nvmf_fc_conn {
        /* number of read/write requests that are outstanding */
        uint16_t cur_fc_rw_depth;
 
-       /* requests that are waiting to obtain xri/buffer */
-       TAILQ_HEAD(, spdk_nvmf_fc_request) pending_queue;
-
        struct spdk_nvmf_fc_association *fc_assoc;
 
-       /* additional FC info here - TBD */
        uint16_t rpi;
 
        /* for association's connection list */
@@ -245,67 +237,68 @@ struct spdk_nvmf_fc_conn {
 
        /* for hwqp's connection list */
        TAILQ_ENTRY(spdk_nvmf_fc_conn) link;
+
+       /* New QP create context. */
+       struct nvmf_fc_ls_op_ctx *create_opd;
 };
 
 /*
- * Structure for maintaining the XRI's
+ * Structure for maintaining the FC exchanges
  */
-struct spdk_nvmf_fc_xri {
-       uint32_t xri;   /* The actual xri value */
+struct spdk_nvmf_fc_xchg {
+       uint32_t xchg_id;   /* The actual xchg identifier */
+
        /* Internal */
-       TAILQ_ENTRY(spdk_nvmf_fc_xri) link;
-       bool is_active;
+       TAILQ_ENTRY(spdk_nvmf_fc_xchg) link;
+       bool active;
+       bool aborted;
+       bool send_abts; /* Valid if is_aborted is set. */
 };
 
-struct spdk_nvmf_fc_poll_group;
+/*
+ *  FC poll group structure
+ */
+struct spdk_nvmf_fc_poll_group {
+       struct spdk_nvmf_transport_poll_group group;
+       struct spdk_nvmf_tgt *nvmf_tgt;
+       uint32_t hwqp_count; /* number of hwqp's assigned to this pg */
+       TAILQ_HEAD(, spdk_nvmf_fc_hwqp) hwqp_list;
+
+       TAILQ_ENTRY(spdk_nvmf_fc_poll_group) link;
+};
 
 /*
  *  HWQP poller structure passed from Master thread
  */
 struct spdk_nvmf_fc_hwqp {
+       enum spdk_fc_hwqp_state state;  /* queue state (for poller) */
        uint32_t lcore_id;   /* core hwqp is running on (for tracing purposes only) */
        struct spdk_thread *thread;  /* thread hwqp is running on */
        uint32_t hwqp_id;    /* A unique id (per physical port) for a hwqp */
        uint32_t rq_size;    /* receive queue size */
-       spdk_nvmf_fc_lld_hwqp_t queues;          /* vendor HW queue set */
+       spdk_nvmf_fc_lld_hwqp_t queues;    /* vendor HW queue set */
        struct spdk_nvmf_fc_port *fc_port; /* HW port structure for these queues */
-       struct spdk_nvmf_fc_poll_group *poll_group;
-
-       void *context;                  /* Vendor Context */
+       struct spdk_nvmf_fc_poll_group *fgroup;
 
+       /* qpair (fc_connection) list */
        TAILQ_HEAD(, spdk_nvmf_fc_conn) connection_list;
        uint32_t num_conns; /* number of connections to queue */
-       uint16_t cid_cnt;   /* used to generate unique conn. id for RQ */
-       uint32_t free_q_slots; /* free q slots available for connections  */
-       enum spdk_fc_hwqp_state state;  /* Poller state (e.g. online, offline) */
 
-       /* Internal */
-       struct spdk_mempool *fc_request_pool;
+       struct spdk_nvmf_fc_request *fc_reqs_buf;
+       TAILQ_HEAD(, spdk_nvmf_fc_request) free_reqs;
        TAILQ_HEAD(, spdk_nvmf_fc_request) in_use_reqs;
 
-       TAILQ_HEAD(, spdk_nvmf_fc_xri) pending_xri_list;
-
        struct spdk_nvmf_fc_errors counters;
-       uint32_t send_frame_xri;
-       uint8_t send_frame_seqid;
 
-       /* Pending LS request waiting for XRI. */
+       /* Pending LS request waiting for FC resource */
        TAILQ_HEAD(, spdk_nvmf_fc_ls_rqst) ls_pending_queue;
 
        /* Sync req list */
        TAILQ_HEAD(, spdk_nvmf_fc_poller_api_queue_sync_args) sync_cbs;
 
        TAILQ_ENTRY(spdk_nvmf_fc_hwqp) link;
-};
-
-struct spdk_nvmf_fc_ls_rsrc_pool {
-       void *assocs_mptr;
-       uint32_t assocs_count;
-       TAILQ_HEAD(, spdk_nvmf_fc_association) assoc_free_list;
 
-       void *conns_mptr;
-       uint32_t conns_count;
-       TAILQ_HEAD(, spdk_nvmf_fc_conn) fc_conn_free_list;
+       void *context;                  /* Vendor specific context data */
 };
 
 /*
@@ -314,11 +307,9 @@ struct spdk_nvmf_fc_ls_rsrc_pool {
 struct spdk_nvmf_fc_port {
        uint8_t port_hdl;
        enum spdk_fc_port_state hw_port_status;
-       uint32_t xri_base;
-       uint32_t xri_count;
        uint16_t fcp_rq_id;
-       struct spdk_ring *xri_ring;
        struct spdk_nvmf_fc_hwqp ls_queue;
+
        uint32_t num_io_queues;
        struct spdk_nvmf_fc_hwqp *io_queues;
        /*
@@ -328,8 +319,7 @@ struct spdk_nvmf_fc_port {
        int     num_nports;
        TAILQ_ENTRY(spdk_nvmf_fc_port) link;
 
-       struct spdk_nvmf_fc_ls_rsrc_pool ls_rsrc_pool;
-       struct spdk_mempool *io_rsrc_pool; /* Pools to store bdev_io's for this port */
+       struct spdk_mempool *io_resource_pool; /* Pools to store bdev_io's for this port */
        void *port_ctx;
 };
 
@@ -342,7 +332,7 @@ struct spdk_nvmf_fc_request {
        uint32_t poller_lcore; /* for tracing purposes only */
        struct spdk_thread *poller_thread;
        uint16_t buf_index;
-       struct spdk_nvmf_fc_xri *xri;
+       struct spdk_nvmf_fc_xchg *xchg;
        uint16_t oxid;
        uint16_t rpi;
        struct spdk_nvmf_fc_conn *fc_conn;
@@ -354,13 +344,14 @@ struct spdk_nvmf_fc_request {
        uint32_t s_id;
        uint32_t d_id;
        TAILQ_ENTRY(spdk_nvmf_fc_request) link;
-       TAILQ_ENTRY(spdk_nvmf_fc_request) pending_link;
+       STAILQ_ENTRY(spdk_nvmf_fc_request) pending_link;
        TAILQ_HEAD(, spdk_nvmf_fc_caller_ctx) abort_cbs;
 };
 
 SPDK_STATIC_ASSERT(!offsetof(struct spdk_nvmf_fc_request, req),
                   "FC request and NVMF request address don't match.");
 
+
 /*
  * NVMF FC Association
  */
@@ -370,12 +361,11 @@ struct spdk_nvmf_fc_association {
        struct spdk_nvmf_fc_nport *tgtport;
        struct spdk_nvmf_fc_remote_port_info *rport;
        struct spdk_nvmf_subsystem *subsystem;
-       struct spdk_nvmf_host *host;
        enum spdk_nvmf_fc_object_state assoc_state;
 
        char host_id[FCNVME_ASSOC_HOSTID_LEN];
-       char host_nqn[FCNVME_ASSOC_HOSTNQN_LEN];
-       char sub_nqn[FCNVME_ASSOC_HOSTNQN_LEN];
+       char host_nqn[SPDK_NVME_NQN_FIELD_SIZE];
+       char sub_nqn[SPDK_NVME_NQN_FIELD_SIZE];
 
        struct spdk_nvmf_fc_conn *aq_conn; /* connection for admin queue */
 
@@ -392,8 +382,8 @@ struct spdk_nvmf_fc_association {
 
        void *ls_del_op_ctx; /* delete assoc. callback list */
 
-       /* req/resp buffers used to send disconnect to initiator */
-       struct spdk_nvmf_fc_send_srsr snd_disconn_bufs;
+       /* disconnect cmd buffers (sent to initiator) */
+       struct spdk_nvmf_fc_srsr_bufs *snd_disconn_bufs;
 };
 
 /*
@@ -430,10 +420,13 @@ enum spdk_nvmf_fc_poller_api {
        SPDK_NVMF_FC_POLLER_API_QUIESCE_QUEUE,
        SPDK_NVMF_FC_POLLER_API_ACTIVATE_QUEUE,
        SPDK_NVMF_FC_POLLER_API_ABTS_RECEIVED,
+       SPDK_NVMF_FC_POLLER_API_REQ_ABORT_COMPLETE,
        SPDK_NVMF_FC_POLLER_API_ADAPTER_EVENT,
        SPDK_NVMF_FC_POLLER_API_AEN,
        SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC,
        SPDK_NVMF_FC_POLLER_API_QUEUE_SYNC_DONE,
+       SPDK_NVMF_FC_POLLER_API_ADD_HWQP,
+       SPDK_NVMF_FC_POLLER_API_REMOVE_HWQP,
 };
 
 /*
@@ -445,6 +438,7 @@ typedef void (*spdk_nvmf_fc_poller_api_cb)(void *cb_data, enum spdk_nvmf_fc_poll
  * Poller API callback data
  */
 struct spdk_nvmf_fc_poller_api_cb_info {
+       struct spdk_thread *cb_thread;
        spdk_nvmf_fc_poller_api_cb cb_func;
        void *cb_data;
        enum spdk_nvmf_fc_poller_api_ret ret;
@@ -465,6 +459,7 @@ struct spdk_nvmf_fc_poller_api_del_connection_args {
        bool send_abts;
        /* internal */
        int fc_request_cnt;
+       bool backend_initiated;
 };
 
 struct spdk_nvmf_fc_poller_api_quiesce_queue_args {
@@ -486,6 +481,7 @@ struct spdk_nvmf_fc_poller_api_abts_recvd_args {
 
 struct spdk_nvmf_fc_poller_api_queue_sync_done_args {
        struct spdk_nvmf_fc_hwqp *hwqp;
+       struct spdk_nvmf_fc_poller_api_cb_info cb_info;
        uint64_t tag;
 };
 
@@ -498,7 +494,7 @@ struct spdk_nvmf_fc_ls_rqst {
        uint32_t rqst_len;
        uint32_t rsp_len;
        uint32_t rpi;
-       struct spdk_nvmf_fc_xri *xri;
+       struct spdk_nvmf_fc_xchg *xchg;
        uint16_t oxid;
        void *private_data; /* for LLD only (LS does not touch) */
        TAILQ_ENTRY(spdk_nvmf_fc_ls_rqst) ls_pending_link;
@@ -515,7 +511,7 @@ struct spdk_nvmf_fc_ls_rqst {
 #define FCNVME_LS_RSVD_SIZE (FCNVME_MAX_LS_BUFFER_SIZE - \
        (sizeof(struct spdk_nvmf_fc_ls_rqst) + FCNVME_MAX_LS_REQ_SIZE + FCNVME_MAX_LS_RSP_SIZE))
 
-struct __attribute__((__packed__)) spdk_nvmf_fc_rq_buf_ls_request {
+struct spdk_nvmf_fc_rq_buf_ls_request {
        uint8_t rqst[FCNVME_MAX_LS_REQ_SIZE];
        uint8_t resp[FCNVME_MAX_LS_RSP_SIZE];
        struct spdk_nvmf_fc_ls_rqst ls_rqst;
@@ -525,6 +521,48 @@ struct __attribute__((__packed__)) spdk_nvmf_fc_rq_buf_ls_request {
 SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fc_rq_buf_ls_request) ==
                   FCNVME_MAX_LS_BUFFER_SIZE, "LS RQ Buffer overflow");
 
+/* Poller API structures (arguments and callback data */
+typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
+
+struct spdk_nvmf_fc_ls_add_conn_api_data {
+       struct spdk_nvmf_fc_poller_api_add_connection_args args;
+       struct spdk_nvmf_fc_ls_rqst *ls_rqst;
+       struct spdk_nvmf_fc_association *assoc;
+       bool aq_conn; /* true if adding connection for new association */
+};
+
+/* Disconnect (connection) request functions */
+struct spdk_nvmf_fc_ls_del_conn_api_data {
+       struct spdk_nvmf_fc_poller_api_del_connection_args args;
+       struct spdk_nvmf_fc_ls_rqst *ls_rqst;
+       struct spdk_nvmf_fc_association *assoc;
+       bool aq_conn; /* true if deleting AQ connection */
+};
+
+/* used by LS disconnect association cmd handling */
+struct spdk_nvmf_fc_ls_disconn_assoc_api_data {
+       struct spdk_nvmf_fc_nport *tgtport;
+       struct spdk_nvmf_fc_ls_rqst *ls_rqst;
+};
+
+/* used by delete association call */
+struct spdk_nvmf_fc_delete_assoc_api_data {
+       struct spdk_nvmf_fc_poller_api_del_connection_args args;
+       struct spdk_nvmf_fc_association *assoc;
+       bool from_ls_rqst;   /* true = request came for LS */
+       spdk_nvmf_fc_del_assoc_cb del_assoc_cb;
+       void *del_assoc_cb_data;
+};
+
+struct nvmf_fc_ls_op_ctx {
+       union {
+               struct spdk_nvmf_fc_ls_add_conn_api_data add_conn;
+               struct spdk_nvmf_fc_ls_del_conn_api_data del_conn;
+               struct spdk_nvmf_fc_ls_disconn_assoc_api_data disconn_assoc;
+               struct spdk_nvmf_fc_delete_assoc_api_data del_assoc;
+       } u;
+       struct  nvmf_fc_ls_op_ctx *next_op_ctx;
+};
 
 struct spdk_nvmf_fc_poller_api_queue_sync_args {
        uint64_t u_id;
@@ -535,6 +573,185 @@ struct spdk_nvmf_fc_poller_api_queue_sync_args {
        TAILQ_ENTRY(spdk_nvmf_fc_poller_api_queue_sync_args) link;
 };
 
+/**
+ * Following defines and structures are used to pass messages between master thread
+ * and FCT driver.
+ */
+enum spdk_fc_event {
+       SPDK_FC_HW_PORT_INIT,
+       SPDK_FC_HW_PORT_ONLINE,
+       SPDK_FC_HW_PORT_OFFLINE,
+       SPDK_FC_HW_PORT_RESET,
+       SPDK_FC_NPORT_CREATE,
+       SPDK_FC_NPORT_DELETE,
+       SPDK_FC_IT_ADD,    /* PRLI */
+       SPDK_FC_IT_DELETE, /* PRLI */
+       SPDK_FC_ABTS_RECV,
+       SPDK_FC_LINK_BREAK,
+       SPDK_FC_HW_PORT_DUMP,
+       SPDK_FC_UNRECOVERABLE_ERR,
+       SPDK_FC_EVENT_MAX,
+};
+
+/**
+ * Arguments for to dump assoc id
+ */
+struct spdk_nvmf_fc_dump_assoc_id_args {
+       uint8_t                           pport_handle;
+       uint16_t                          nport_handle;
+       uint32_t                          assoc_id;
+};
+
+/**
+ * Arguments for HW port init event.
+ */
+struct spdk_nvmf_fc_hw_port_init_args {
+       uint32_t                       ls_queue_size;
+       spdk_nvmf_fc_lld_hwqp_t        ls_queue;
+       uint32_t                       io_queue_size;
+       uint32_t                       io_queue_cnt;
+       spdk_nvmf_fc_lld_hwqp_t       *io_queues;
+       void                          *cb_ctx;
+       void                          *port_ctx;
+       uint8_t                        port_handle;
+       uint8_t                        nvme_aq_index;  /* io_queue used for nvme admin queue */
+       uint16_t                       fcp_rq_id; /* Base rq ID of SCSI queue */
+};
+
+/**
+ * Arguments for HW port link break event.
+ */
+struct spdk_nvmf_hw_port_link_break_args {
+       uint8_t port_handle;
+       void   *cb_ctx;
+};
+
+/**
+ * Arguments for HW port online event.
+ */
+struct spdk_nvmf_fc_hw_port_online_args {
+       uint8_t port_handle;
+       void   *cb_ctx;
+};
+
+/**
+ * Arguments for HW port offline event.
+ */
+struct spdk_nvmf_fc_hw_port_offline_args {
+       uint8_t port_handle;
+       void   *cb_ctx;
+};
+
+/**
+ * Arguments for n-port add event.
+ */
+struct spdk_nvmf_fc_nport_create_args {
+       uint8_t                     port_handle;
+       uint16_t                    nport_handle;
+       struct spdk_uuid            container_uuid; /* UUID of the nports container */
+       struct spdk_uuid            nport_uuid;     /* Unique UUID for the nport */
+       uint32_t                    d_id;
+       struct spdk_nvmf_fc_wwn fc_nodename;
+       struct spdk_nvmf_fc_wwn fc_portname;
+       uint32_t                    subsys_id; /* Subsystemid */
+       char                        port_id[SPDK_NVMF_PORT_ID_MAX_LEN];
+       void                       *cb_ctx;
+};
+
+/**
+ * Arguments for n-port delete event.
+ */
+struct spdk_nvmf_fc_nport_delete_args {
+       uint8_t  port_handle;
+       uint32_t nport_handle;
+       uint32_t subsys_id; /* Subsystem id */
+       void    *cb_ctx;
+};
+
+/**
+ * Arguments for I_T add event.
+ */
+struct spdk_nvmf_fc_hw_i_t_add_args {
+       uint8_t                      port_handle;
+       uint32_t                     nport_handle;
+       uint16_t                     itn_handle;
+       uint32_t                     rpi;
+       uint32_t                     s_id;
+       uint32_t                     initiator_prli_info;
+       uint32_t                     target_prli_info; /* populated by the SPDK master */
+       struct spdk_nvmf_fc_wwn  fc_nodename;
+       struct spdk_nvmf_fc_wwn  fc_portname;
+       void                        *cb_ctx;
+};
+
+/**
+ * Arguments for I_T delete event.
+ */
+struct spdk_nvmf_fc_hw_i_t_delete_args {
+       uint8_t  port_handle;
+       uint32_t nport_handle;
+       uint16_t itn_handle;    /* Only used by FC LLD driver; unused in SPDK */
+       uint32_t rpi;
+       uint32_t s_id;
+       void    *cb_ctx;
+};
+
+/**
+ * Arguments for ABTS  event.
+ */
+struct spdk_nvmf_fc_abts_args {
+       uint8_t  port_handle;
+       uint32_t nport_handle;
+       uint32_t rpi;
+       uint16_t oxid, rxid;
+       void    *cb_ctx;
+};
+
+/**
+ * Arguments for link break event.
+ */
+struct spdk_nvmf_fc_link_break_args {
+       uint8_t port_handle;
+};
+
+/**
+ * Arguments for port reset event.
+ */
+struct spdk_nvmf_fc_hw_port_reset_args {
+       uint8_t    port_handle;
+       bool       dump_queues;
+       char       reason[SPDK_FC_HW_DUMP_REASON_STR_MAX_SIZE];
+       uint32_t **dump_buf;
+       void      *cb_ctx;
+};
+
+/**
+ * Arguments for unrecoverable error event
+ */
+struct spdk_nvmf_fc_unrecoverable_error_event_args {
+};
+
+/**
+ * Callback function to the FCT driver.
+ */
+typedef void (*spdk_nvmf_fc_callback)(uint8_t port_handle,
+                                     enum spdk_fc_event event_type,
+                                     void *arg, int err);
+
+/**
+ * Enqueue an FCT event to master thread
+ *
+ * \param event_type Type of the event.
+ * \param args Pointer to the argument structure.
+ * \param cb_func Callback function into fc driver.
+ *
+ * \return 0 on success, non-zero on failure.
+ */
+int
+nvmf_fc_master_enqueue_event(enum spdk_fc_event event_type,
+                            void *args,
+                            spdk_nvmf_fc_callback cb_func);
+
 /*
  * dump info
  */
@@ -545,7 +762,7 @@ struct spdk_nvmf_fc_queue_dump_info {
 #define SPDK_FC_HW_DUMP_BUF_SIZE (10 * 4096)
 
 static inline void
-spdk_nvmf_fc_dump_buf_print(struct spdk_nvmf_fc_queue_dump_info *dump_info, char *fmt, ...)
+nvmf_fc_dump_buf_print(struct spdk_nvmf_fc_queue_dump_info *dump_info, char *fmt, ...)
 {
        uint64_t buffer_size = SPDK_FC_HW_DUMP_BUF_SIZE;
        int32_t avail = (int32_t)(buffer_size - dump_info->offset);
@@ -578,92 +795,29 @@ struct spdk_nvmf_fc_caller_ctx {
 };
 
 /*
- * Low level FC driver function table (functions provided by vendor FC device driver)
+ * NVMF FC Exchange Info (for debug)
  */
-struct spdk_nvmf_fc_ll_drvr_ops {
-
-       /* initialize the low level driver */
-       int (*lld_init)(void);
-
-       /* low level driver finish */
-       void (*lld_fini)(void);
-
-       /* initialize hw queues */
-       int (*init_q)(struct spdk_nvmf_fc_hwqp *hwqp);
-
-       void (*reinit_q)(spdk_nvmf_fc_lld_hwqp_t queues_prev,
-                        spdk_nvmf_fc_lld_hwqp_t queues_curr);
-
-       /* initialize hw queue buffers */
-       int (*init_q_buffers)(struct spdk_nvmf_fc_hwqp *hwqp);
-
-       /* poll the hw queues for requests */
-       uint32_t (*poll_queue)(struct spdk_nvmf_fc_hwqp *hwqp);
-
-       /* receive data (for data-in requests) */
-       int (*recv_data)(struct spdk_nvmf_fc_request *fc_req);
-
-       /* send data (for data-out requests) */
-       int (*send_data)(struct spdk_nvmf_fc_request *fc_req);
-
-       /* release hw queust buffer */
-       void (*q_buffer_release)(struct spdk_nvmf_fc_hwqp *hwqp, uint16_t buff_idx);
-
-       /* transmist nvme response */
-       int (*xmt_rsp)(struct spdk_nvmf_fc_request *fc_req, uint8_t *ersp_buf, uint32_t ersp_len);
-
-       /* transmist LS response */
-       int (*xmt_ls_rsp)(struct spdk_nvmf_fc_nport *tgtport, struct spdk_nvmf_fc_ls_rqst *ls_rqst);
-
-       /* issue abts */
-       int (*issue_abort)(struct spdk_nvmf_fc_hwqp *hwqp, struct spdk_nvmf_fc_xri *xri,
-                          bool send_abts, spdk_nvmf_fc_caller_cb cb, void *cb_args);
-
-       /* transmit abts response */
-       int (*xmt_bls_rsp)(struct spdk_nvmf_fc_hwqp *hwqp, uint16_t ox_id, uint16_t rx_id, uint16_t rpi,
-                          bool rjt, uint8_t rjt_exp, spdk_nvmf_fc_caller_cb cb, void *cb_args);
-
-       /* transmit single request - single response */
-       int (*xmt_srsr_req)(struct spdk_nvmf_fc_hwqp *hwqp, struct spdk_nvmf_fc_send_srsr *srsr,
-                           spdk_nvmf_fc_caller_cb cb, void *cb_args);
-
-       /* issue queue marker (abts processing) */
-       int (*issue_q_marker)(struct spdk_nvmf_fc_hwqp *hwqp, uint64_t u_id, uint16_t skip_rq);
-
-       /* assign a new connection to a hwqp (return connection ID) */
-       struct spdk_nvmf_fc_hwqp *(*assign_conn_to_hwqp)(
-               struct spdk_nvmf_fc_hwqp *queues, uint32_t num_queues,
-               uint64_t *conn_id, uint32_t sq_size, bool for_aq);
-
-       /* get the hwqp from the given connection id */
-       struct spdk_nvmf_fc_hwqp *(*get_hwqp_from_conn_id)(struct spdk_nvmf_fc_hwqp *hwqp,
-                       uint32_t num_queues, uint64_t conn_id);
-
-       /* release connection ID (done with using it) */
-       void (*release_conn)(struct spdk_nvmf_fc_hwqp *hwqp, uint64_t conn_id, uint32_t sq_size);
-
-       /* dump all queue info into dump_info */
-       void (*dump_all_queues)(struct spdk_nvmf_fc_hwqp *ls_queues,
-                               struct spdk_nvmf_fc_hwqp *io_queues,
-                               uint32_t num_queues,
-                               struct spdk_nvmf_fc_queue_dump_info *dump_info);
+struct spdk_nvmf_fc_xchg_info {
+       uint32_t xchg_base;
+       uint32_t xchg_total_count;
+       uint32_t xchg_avail_count;
+       uint32_t send_frame_xchg_id;
+       uint8_t send_frame_seqid;
 };
 
-extern struct spdk_nvmf_fc_ll_drvr_ops spdk_nvmf_fc_lld_ops;
-
 /*
  * NVMF FC inline and function prototypes
  */
 
 static inline struct spdk_nvmf_fc_request *
-spdk_nvmf_fc_get_fc_req(struct spdk_nvmf_request *req)
+nvmf_fc_get_fc_req(struct spdk_nvmf_request *req)
 {
        return (struct spdk_nvmf_fc_request *)
               ((uintptr_t)req - offsetof(struct spdk_nvmf_fc_request, req));
 }
 
 static inline bool
-spdk_nvmf_fc_is_port_dead(struct spdk_nvmf_fc_hwqp *hwqp)
+nvmf_fc_is_port_dead(struct spdk_nvmf_fc_hwqp *hwqp)
 {
        switch (hwqp->fc_port->hw_port_status) {
        case SPDK_FC_PORT_QUIESCED:
@@ -674,7 +828,7 @@ spdk_nvmf_fc_is_port_dead(struct spdk_nvmf_fc_hwqp *hwqp)
 }
 
 static inline bool
-spdk_nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
+nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
 {
        switch (fc_req->state) {
        case SPDK_NVMF_FC_REQ_READ_XFER:
@@ -688,136 +842,115 @@ spdk_nvmf_fc_req_in_xfer(struct spdk_nvmf_fc_request *fc_req)
        }
 }
 
-typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
-int spdk_nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
-                                   uint64_t assoc_id, bool send_abts,
-                                   spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
-                                   void *cb_data);
-
-void spdk_nvmf_fc_ls_init(struct spdk_nvmf_fc_port *fc_port);
-
-void spdk_nvmf_fc_ls_fini(struct spdk_nvmf_fc_port *fc_port);
-
-struct spdk_nvmf_fc_port *spdk_nvmf_fc_port_list_get(uint8_t port_hdl);
-
-int spdk_nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport,
-                                enum spdk_nvmf_fc_object_state state);
-
-int spdk_nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc,
-                                enum spdk_nvmf_fc_object_state state);
-
-bool spdk_nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport,
-                                    struct spdk_nvmf_fc_remote_port_info *rem_port);
-
-bool spdk_nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport,
-                                       struct spdk_nvmf_fc_remote_port_info *rem_port);
-
-void spdk_nvmf_fc_init_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp);
-
-void spdk_nvmf_fc_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp,
-                                      void *queues_curr);
-
-void spdk_nvmf_fc_init_poller(struct spdk_nvmf_fc_port *fc_port,
-                             struct spdk_nvmf_fc_hwqp *hwqp);
-
-void spdk_nvmf_fc_add_hwqp_to_poller(struct spdk_nvmf_fc_hwqp *hwqp, bool admin_q);
+static inline void
+nvmf_fc_create_trid(struct spdk_nvme_transport_id *trid, uint64_t n_wwn, uint64_t p_wwn)
+{
+       spdk_nvme_trid_populate_transport(trid, SPDK_NVME_TRANSPORT_FC);
+       trid->adrfam = SPDK_NVMF_ADRFAM_FC;
+       snprintf(trid->trsvcid, sizeof(trid->trsvcid), "none");
+       snprintf(trid->traddr, sizeof(trid->traddr), "nn-0x%lx:pn-0x%lx", n_wwn, p_wwn);
+}
 
-void spdk_nvmf_fc_remove_hwqp_from_poller(struct spdk_nvmf_fc_hwqp *hwqp);
+void nvmf_fc_ls_init(struct spdk_nvmf_fc_port *fc_port);
 
-bool spdk_nvmf_fc_port_is_offline(struct spdk_nvmf_fc_port *fc_port);
+void nvmf_fc_ls_fini(struct spdk_nvmf_fc_port *fc_port);
 
-int spdk_nvmf_fc_port_set_offline(struct spdk_nvmf_fc_port *fc_port);
+void nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst);
+void nvmf_fc_ls_add_conn_failure(
+       struct spdk_nvmf_fc_association *assoc,
+       struct spdk_nvmf_fc_ls_rqst *ls_rqst,
+       struct spdk_nvmf_fc_conn *fc_conn,
+       bool aq_conn);
 
-bool spdk_nvmf_fc_port_is_online(struct spdk_nvmf_fc_port *fc_port);
+void nvmf_fc_init_hwqp(struct spdk_nvmf_fc_port *fc_port, struct spdk_nvmf_fc_hwqp *hwqp);
 
-int spdk_nvmf_fc_port_set_online(struct spdk_nvmf_fc_port *fc_port);
+void nvmf_fc_init_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp);
 
-int spdk_nvmf_fc_hwqp_port_set_online(struct spdk_nvmf_fc_hwqp *hwqp);
+struct spdk_nvmf_fc_conn *nvmf_fc_hwqp_find_fc_conn(struct spdk_nvmf_fc_hwqp *hwqp,
+               uint64_t conn_id);
 
-int spdk_nvmf_fc_hwqp_port_set_offline(struct spdk_nvmf_fc_hwqp *hwqp);
+void nvmf_fc_hwqp_reinit_poller_queues(struct spdk_nvmf_fc_hwqp *hwqp, void *queues_curr);
 
-int spdk_nvmf_fc_rport_set_state(struct spdk_nvmf_fc_remote_port_info *rport,
-                                enum spdk_nvmf_fc_object_state state);
+struct spdk_nvmf_fc_port *nvmf_fc_port_lookup(uint8_t port_hdl);
 
-void spdk_nvmf_fc_port_list_add(struct spdk_nvmf_fc_port *fc_port);
+bool nvmf_fc_port_is_offline(struct spdk_nvmf_fc_port *fc_port);
 
-struct spdk_nvmf_fc_nport *spdk_nvmf_fc_nport_get(uint8_t port_hdl, uint16_t nport_hdl);
+int nvmf_fc_port_set_offline(struct spdk_nvmf_fc_port *fc_port);
 
-int spdk_nvmf_fc_port_add_nport(struct spdk_nvmf_fc_port *fc_port,
-                               struct spdk_nvmf_fc_nport *nport);
+bool nvmf_fc_port_is_online(struct spdk_nvmf_fc_port *fc_port);
 
-uint32_t spdk_nvmf_fc_nport_get_association_count(struct spdk_nvmf_fc_nport *nport);
+int nvmf_fc_port_set_online(struct spdk_nvmf_fc_port *fc_port);
 
-int spdk_nvmf_fc_port_remove_nport(struct spdk_nvmf_fc_port *fc_port,
-                                  struct spdk_nvmf_fc_nport *nport);
+int nvmf_fc_rport_set_state(struct spdk_nvmf_fc_remote_port_info *rport,
+                           enum spdk_nvmf_fc_object_state state);
 
-uint32_t spdk_nvmf_fc_get_prli_service_params(void);
+void nvmf_fc_port_add(struct spdk_nvmf_fc_port *fc_port);
 
-bool spdk_nvmf_fc_nport_is_rport_empty(struct spdk_nvmf_fc_nport *nport);
+int nvmf_fc_port_add_nport(struct spdk_nvmf_fc_port *fc_port,
+                          struct spdk_nvmf_fc_nport *nport);
 
-void spdk_nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport,
-                                   uint16_t rpi, uint16_t oxid,
-                                   uint16_t rxid);
+int nvmf_fc_port_remove_nport(struct spdk_nvmf_fc_port *fc_port,
+                             struct spdk_nvmf_fc_nport *nport);
 
-void spdk_nvmf_fc_dump_all_queues(struct spdk_nvmf_fc_port *fc_port,
-                                 struct spdk_nvmf_fc_queue_dump_info *dump_info);
+struct spdk_nvmf_fc_nport *nvmf_fc_nport_find(uint8_t port_hdl, uint16_t nport_hdl);
 
-void spdk_nvmf_fc_handle_ls_rqst(struct spdk_nvmf_fc_ls_rqst *ls_rqst);
+int nvmf_fc_nport_set_state(struct spdk_nvmf_fc_nport *nport,
+                           enum spdk_nvmf_fc_object_state state);
 
-int spdk_nvmf_fc_xmt_ls_rsp(struct spdk_nvmf_fc_nport *tgtport,
-                           struct spdk_nvmf_fc_ls_rqst *ls_rqst);
+bool nvmf_fc_nport_add_rem_port(struct spdk_nvmf_fc_nport *nport,
+                               struct spdk_nvmf_fc_remote_port_info *rem_port);
 
-struct spdk_nvmf_fc_nport *spdk_nvmf_bcm_req_fc_nport_get(struct spdk_nvmf_request *req);
+bool nvmf_fc_nport_remove_rem_port(struct spdk_nvmf_fc_nport *nport,
+                                  struct spdk_nvmf_fc_remote_port_info *rem_port);
 
-struct spdk_nvmf_fc_association *spdk_nvmf_fc_get_ctrlr_assoc(struct spdk_nvmf_ctrlr *ctrlr);
+bool nvmf_fc_nport_has_no_rport(struct spdk_nvmf_fc_nport *nport);
 
-bool spdk_nvmf_fc_nport_is_association_empty(struct spdk_nvmf_fc_nport *nport);
+int nvmf_fc_assoc_set_state(struct spdk_nvmf_fc_association *assoc,
+                           enum spdk_nvmf_fc_object_state state);
 
-int spdk_nvmf_fc_xmt_srsr_req(struct spdk_nvmf_fc_hwqp *hwqp,
-                             struct spdk_nvmf_fc_send_srsr *srsr,
-                             spdk_nvmf_fc_caller_cb cb, void *cb_args);
+int nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
+                              uint64_t assoc_id, bool send_abts, bool backend_initiated,
+                              spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
+                              void *cb_data);
 
-uint32_t spdk_nvmf_fc_get_num_nport_ctrlrs_in_subsystem(uint8_t port_hdl, uint16_t nport_hdl,
-               struct spdk_nvmf_subsystem *subsys);
+bool nvmf_ctrlr_is_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
+                           struct spdk_nvmf_ctrlr *ctrlr);
 
-bool spdk_nvmf_fc_is_spdk_ctrlr_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
-               struct spdk_nvmf_ctrlr *ctrlr);
+void nvmf_fc_assign_queue_to_master_thread(struct spdk_nvmf_fc_hwqp *hwqp);
 
-int spdk_nvmf_fc_get_ctrlr_init_traddr(char *traddr, struct spdk_nvmf_ctrlr *ctrlr);
+void nvmf_fc_poll_group_add_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
 
-uint32_t spdk_nvmf_fc_get_hwqp_id(struct spdk_nvmf_request *req);
+void nvmf_fc_poll_group_remove_hwqp(struct spdk_nvmf_fc_hwqp *hwqp);
 
-void spdk_nvmf_fc_req_abort(struct spdk_nvmf_fc_request *fc_req,
-                           bool send_abts, spdk_nvmf_fc_caller_cb cb,
-                           void *cb_args);
+int nvmf_fc_hwqp_set_online(struct spdk_nvmf_fc_hwqp *hwqp);
 
-int spdk_nvmf_fc_add_port_listen(void *arg1, void *arg2);
+int nvmf_fc_hwqp_set_offline(struct spdk_nvmf_fc_hwqp *hwqp);
 
-int spdk_nvmf_fc_remove_port_listen(void *arg1, void *arg2);
+uint32_t nvmf_fc_get_prli_service_params(void);
 
-void spdk_nvmf_fc_subsys_connect_cb(void *cb_ctx,
-                                   struct spdk_nvmf_request *req);
+void nvmf_fc_handle_abts_frame(struct spdk_nvmf_fc_nport *nport, uint16_t rpi, uint16_t oxid,
+                              uint16_t rxid);
 
-void spdk_nvmf_fc_subsys_disconnect_cb(void *cb_ctx,
-                                      struct spdk_nvmf_qpair *qpair);
+void nvmf_fc_request_abort(struct spdk_nvmf_fc_request *fc_req, bool send_abts,
+                          spdk_nvmf_fc_caller_cb cb, void *cb_args);
 
-uint32_t spdk_nvmf_fc_get_master_lcore(void);
+struct spdk_nvmf_tgt *nvmf_fc_get_tgt(void);
 
-struct spdk_thread *spdk_nvmf_fc_get_master_thread(void);
+struct spdk_thread *nvmf_fc_get_master_thread(void);
 
 /*
- * These functions are used by low level FC driver
+ * These functions are called by low level FC driver
  */
 
 static inline struct spdk_nvmf_fc_conn *
-spdk_nvmf_fc_get_conn(struct spdk_nvmf_qpair *qpair)
+nvmf_fc_get_conn(struct spdk_nvmf_qpair *qpair)
 {
        return (struct spdk_nvmf_fc_conn *)
               ((uintptr_t)qpair - offsetof(struct spdk_nvmf_fc_conn, qpair));
 }
 
 static inline uint16_t
-spdk_nvmf_fc_advance_conn_sqhead(struct spdk_nvmf_qpair *qpair)
+nvmf_fc_advance_conn_sqhead(struct spdk_nvmf_qpair *qpair)
 {
        /* advance sq_head pointer - wrap if needed */
        qpair->sq_head = (qpair->sq_head == qpair->sq_head_max) ?
@@ -826,7 +959,7 @@ spdk_nvmf_fc_advance_conn_sqhead(struct spdk_nvmf_qpair *qpair)
 }
 
 static inline bool
-spdk_nvmf_fc_use_send_frame(struct spdk_nvmf_request *req)
+nvmf_fc_use_send_frame(struct spdk_nvmf_request *req)
 {
        /* For now use for only keepalives. */
        if (req->qpair->qid == 0 &&
@@ -836,36 +969,31 @@ spdk_nvmf_fc_use_send_frame(struct spdk_nvmf_request *req)
        return false;
 }
 
-enum spdk_nvmf_fc_poller_api_ret spdk_nvmf_fc_poller_api_func(
+enum spdk_nvmf_fc_poller_api_ret nvmf_fc_poller_api_func(
        struct spdk_nvmf_fc_hwqp *hwqp,
        enum spdk_nvmf_fc_poller_api api,
        void *api_args);
 
-int spdk_nvmf_fc_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx,
+int nvmf_fc_hwqp_process_frame(struct spdk_nvmf_fc_hwqp *hwqp, uint32_t buff_idx,
                               struct spdk_nvmf_fc_frame_hdr *frame,
                               struct spdk_nvmf_fc_buffer_desc *buffer, uint32_t plen);
 
-void spdk_nvmf_fc_process_pending_req(struct spdk_nvmf_fc_hwqp *hwqp);
-
-void spdk_nvmf_fc_process_pending_ls_rqst(struct spdk_nvmf_fc_hwqp *hwqp);
+void nvmf_fc_hwqp_process_pending_reqs(struct spdk_nvmf_fc_hwqp *hwqp);
 
-void spdk_nvmf_fc_req_set_state(struct spdk_nvmf_fc_request *fc_req,
-                               enum spdk_nvmf_fc_request_state state);
+void nvmf_fc_hwqp_process_pending_ls_rqsts(struct spdk_nvmf_fc_hwqp *hwqp);
 
-void spdk_nvmf_fc_free_req(struct spdk_nvmf_fc_request *fc_req);
+void nvmf_fc_request_set_state(struct spdk_nvmf_fc_request *fc_req,
+                              enum spdk_nvmf_fc_request_state state);
 
-void spdk_nvmf_fc_req_abort_complete(void *arg1);
+char *nvmf_fc_request_get_state_str(int state);
 
-bool spdk_nvmf_fc_send_ersp_required(struct spdk_nvmf_fc_request *fc_req,
-                                    uint32_t rsp_cnt, uint32_t xfer_len);
+void _nvmf_fc_request_free(struct spdk_nvmf_fc_request *fc_req);
 
-struct spdk_nvmf_fc_xri *spdk_nvmf_fc_get_xri(struct spdk_nvmf_fc_hwqp *hwqp);
+void nvmf_fc_request_abort_complete(void *arg1);
 
-int spdk_nvmf_fc_put_xri(struct spdk_nvmf_fc_hwqp *hwqp,
-                        struct spdk_nvmf_fc_xri *xri);
+bool nvmf_fc_send_ersp_required(struct spdk_nvmf_fc_request *fc_req,
+                               uint32_t rsp_cnt, uint32_t xfer_len);
 
-void spdk_nvmf_fc_release_xri(struct spdk_nvmf_fc_hwqp *hwqp,
-                             struct spdk_nvmf_fc_xri *xri, bool xb, bool abts);
+int nvmf_fc_handle_rsp(struct spdk_nvmf_fc_request *req);
 
-int spdk_nvmf_fc_handle_rsp(struct spdk_nvmf_fc_request *req);
 #endif