162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#include <linux/socket.h> 362306a36Sopenharmony_ci#include <linux/in.h> 462306a36Sopenharmony_ci#include <linux/in6.h> 562306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 662306a36Sopenharmony_ci#include <rdma/rdma_cm.h> 762306a36Sopenharmony_ci#include <rdma/rw.h> 862306a36Sopenharmony_ci#include <scsi/iser.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define DRV_NAME "isert" 1262306a36Sopenharmony_ci#define PFX DRV_NAME ": " 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#define isert_dbg(fmt, arg...) \ 1562306a36Sopenharmony_ci do { \ 1662306a36Sopenharmony_ci if (unlikely(isert_debug_level > 2)) \ 1762306a36Sopenharmony_ci printk(KERN_DEBUG PFX "%s: " fmt,\ 1862306a36Sopenharmony_ci __func__ , ## arg); \ 1962306a36Sopenharmony_ci } while (0) 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define isert_warn(fmt, arg...) \ 2262306a36Sopenharmony_ci do { \ 2362306a36Sopenharmony_ci if (unlikely(isert_debug_level > 0)) \ 2462306a36Sopenharmony_ci pr_warn(PFX "%s: " fmt, \ 2562306a36Sopenharmony_ci __func__ , ## arg); \ 2662306a36Sopenharmony_ci } while (0) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define isert_info(fmt, arg...) \ 2962306a36Sopenharmony_ci do { \ 3062306a36Sopenharmony_ci if (unlikely(isert_debug_level > 1)) \ 3162306a36Sopenharmony_ci pr_info(PFX "%s: " fmt, \ 3262306a36Sopenharmony_ci __func__ , ## arg); \ 3362306a36Sopenharmony_ci } while (0) 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define isert_err(fmt, arg...) \ 3662306a36Sopenharmony_ci pr_err(PFX "%s: " fmt, __func__ , ## arg) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* Constant PDU lengths calculations */ 3962306a36Sopenharmony_ci#define ISER_HEADERS_LEN (sizeof(struct iser_ctrl) + \ 4062306a36Sopenharmony_ci sizeof(struct iscsi_hdr)) 4162306a36Sopenharmony_ci#define ISER_RX_PAYLOAD_SIZE (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* QP settings */ 4462306a36Sopenharmony_ci/* Maximal bounds on received asynchronous PDUs */ 4562306a36Sopenharmony_ci#define ISERT_MAX_TX_MISC_PDUS 4 /* NOOP_IN(2) , ASYNC_EVENT(2) */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define ISERT_MAX_RX_MISC_PDUS 6 /* 4862306a36Sopenharmony_ci * NOOP_OUT(2), TEXT(1), 4962306a36Sopenharmony_ci * SCSI_TMFUNC(2), LOGOUT(1) 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* from libiscsi.h, must be power of 2 */ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define ISERT_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define ISERT_MIN_POSTED_RX (ISCSI_DEF_XMIT_CMDS_MAX >> 2) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define ISERT_QP_MAX_REQ_DTOS (ISCSI_DEF_XMIT_CMDS_MAX + \ 5962306a36Sopenharmony_ci ISERT_MAX_TX_MISC_PDUS + \ 6062306a36Sopenharmony_ci ISERT_MAX_RX_MISC_PDUS) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* 6362306a36Sopenharmony_ci * RX size is default of 8k plus headers, but data needs to align to 6462306a36Sopenharmony_ci * 512 boundary, so use 1024 to have the extra space for alignment. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci#define ISER_RX_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 1024) 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* Minimum I/O size is 512KB */ 6962306a36Sopenharmony_ci#define ISCSI_ISER_MIN_SG_TABLESIZE 128 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* Maximum support is 16MB I/O size */ 7262306a36Sopenharmony_ci#define ISCSI_ISER_MAX_SG_TABLESIZE 4096 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cienum isert_desc_type { 7562306a36Sopenharmony_ci ISCSI_TX_CONTROL, 7662306a36Sopenharmony_ci ISCSI_TX_DATAIN 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cienum iser_conn_state { 8062306a36Sopenharmony_ci ISER_CONN_INIT, 8162306a36Sopenharmony_ci ISER_CONN_UP, 8262306a36Sopenharmony_ci ISER_CONN_BOUND, 8362306a36Sopenharmony_ci ISER_CONN_FULL_FEATURE, 8462306a36Sopenharmony_ci ISER_CONN_TERMINATING, 8562306a36Sopenharmony_ci ISER_CONN_DOWN, 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistruct iser_rx_desc { 8962306a36Sopenharmony_ci char buf[ISER_RX_SIZE]; 9062306a36Sopenharmony_ci u64 dma_addr; 9162306a36Sopenharmony_ci struct ib_sge rx_sg; 9262306a36Sopenharmony_ci struct ib_cqe rx_cqe; 9362306a36Sopenharmony_ci bool in_use; 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic inline struct iser_rx_desc *cqe_to_rx_desc(struct ib_cqe *cqe) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci return container_of(cqe, struct iser_rx_desc, rx_cqe); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic void *isert_get_iser_hdr(struct iser_rx_desc *desc) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci return PTR_ALIGN(desc->buf + ISER_HEADERS_LEN, 512) - ISER_HEADERS_LEN; 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic size_t isert_get_hdr_offset(struct iser_rx_desc *desc) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci return isert_get_iser_hdr(desc) - (void *)desc->buf; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic void *isert_get_iscsi_hdr(struct iser_rx_desc *desc) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci return isert_get_iser_hdr(desc) + sizeof(struct iser_ctrl); 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic void *isert_get_data(struct iser_rx_desc *desc) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci void *data = isert_get_iser_hdr(desc) + ISER_HEADERS_LEN; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci WARN_ON((uintptr_t)data & 511); 12162306a36Sopenharmony_ci return data; 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistruct iser_tx_desc { 12562306a36Sopenharmony_ci struct iser_ctrl iser_header; 12662306a36Sopenharmony_ci struct iscsi_hdr iscsi_header; 12762306a36Sopenharmony_ci enum isert_desc_type type; 12862306a36Sopenharmony_ci u64 dma_addr; 12962306a36Sopenharmony_ci struct ib_sge tx_sg[2]; 13062306a36Sopenharmony_ci struct ib_cqe tx_cqe; 13162306a36Sopenharmony_ci int num_sge; 13262306a36Sopenharmony_ci struct ib_send_wr send_wr; 13362306a36Sopenharmony_ci} __packed; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic inline struct iser_tx_desc *cqe_to_tx_desc(struct ib_cqe *cqe) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci return container_of(cqe, struct iser_tx_desc, tx_cqe); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistruct isert_cmd { 14162306a36Sopenharmony_ci uint32_t read_stag; 14262306a36Sopenharmony_ci uint32_t write_stag; 14362306a36Sopenharmony_ci uint64_t read_va; 14462306a36Sopenharmony_ci uint64_t write_va; 14562306a36Sopenharmony_ci uint32_t inv_rkey; 14662306a36Sopenharmony_ci u64 pdu_buf_dma; 14762306a36Sopenharmony_ci u32 pdu_buf_len; 14862306a36Sopenharmony_ci struct isert_conn *conn; 14962306a36Sopenharmony_ci struct iscsit_cmd *iscsit_cmd; 15062306a36Sopenharmony_ci struct iser_tx_desc tx_desc; 15162306a36Sopenharmony_ci struct iser_rx_desc *rx_desc; 15262306a36Sopenharmony_ci struct rdma_rw_ctx rw; 15362306a36Sopenharmony_ci struct work_struct comp_work; 15462306a36Sopenharmony_ci struct scatterlist sg; 15562306a36Sopenharmony_ci bool ctx_init_done; 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci return container_of(desc, struct isert_cmd, tx_desc); 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistruct isert_device; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistruct isert_conn { 16662306a36Sopenharmony_ci enum iser_conn_state state; 16762306a36Sopenharmony_ci u32 responder_resources; 16862306a36Sopenharmony_ci u32 initiator_depth; 16962306a36Sopenharmony_ci bool pi_support; 17062306a36Sopenharmony_ci struct iser_rx_desc *login_desc; 17162306a36Sopenharmony_ci char *login_rsp_buf; 17262306a36Sopenharmony_ci int login_req_len; 17362306a36Sopenharmony_ci u64 login_rsp_dma; 17462306a36Sopenharmony_ci struct iser_rx_desc *rx_descs; 17562306a36Sopenharmony_ci struct ib_recv_wr rx_wr[ISERT_QP_MAX_RECV_DTOS]; 17662306a36Sopenharmony_ci struct iscsit_conn *conn; 17762306a36Sopenharmony_ci struct list_head node; 17862306a36Sopenharmony_ci struct completion login_comp; 17962306a36Sopenharmony_ci struct completion login_req_comp; 18062306a36Sopenharmony_ci struct iser_tx_desc login_tx_desc; 18162306a36Sopenharmony_ci struct rdma_cm_id *cm_id; 18262306a36Sopenharmony_ci struct ib_qp *qp; 18362306a36Sopenharmony_ci struct ib_cq *cq; 18462306a36Sopenharmony_ci u32 cq_size; 18562306a36Sopenharmony_ci struct isert_device *device; 18662306a36Sopenharmony_ci struct mutex mutex; 18762306a36Sopenharmony_ci struct kref kref; 18862306a36Sopenharmony_ci struct work_struct release_work; 18962306a36Sopenharmony_ci bool logout_posted; 19062306a36Sopenharmony_ci bool snd_w_inv; 19162306a36Sopenharmony_ci wait_queue_head_t rem_wait; 19262306a36Sopenharmony_ci bool dev_removed; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistruct isert_device { 19662306a36Sopenharmony_ci bool pi_capable; 19762306a36Sopenharmony_ci int refcount; 19862306a36Sopenharmony_ci struct ib_device *ib_device; 19962306a36Sopenharmony_ci struct ib_pd *pd; 20062306a36Sopenharmony_ci struct isert_comp *comps; 20162306a36Sopenharmony_ci int comps_used; 20262306a36Sopenharmony_ci struct list_head dev_node; 20362306a36Sopenharmony_ci}; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistruct isert_np { 20662306a36Sopenharmony_ci struct iscsi_np *np; 20762306a36Sopenharmony_ci struct semaphore sem; 20862306a36Sopenharmony_ci struct rdma_cm_id *cm_id; 20962306a36Sopenharmony_ci struct mutex mutex; 21062306a36Sopenharmony_ci struct list_head accepted; 21162306a36Sopenharmony_ci struct list_head pending; 21262306a36Sopenharmony_ci}; 213