162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright (c) 2005 Cisco Systems. All rights reserved. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * This software is available to you under a choice of one of two 562306a36Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 662306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 762306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the 862306a36Sopenharmony_ci * OpenIB.org BSD license below: 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or 1162306a36Sopenharmony_ci * without modification, are permitted provided that the following 1262306a36Sopenharmony_ci * conditions are met: 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * - Redistributions of source code must retain the above 1562306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 1662306a36Sopenharmony_ci * disclaimer. 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above 1962306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 2062306a36Sopenharmony_ci * disclaimer in the documentation and/or other materials 2162306a36Sopenharmony_ci * provided with the distribution. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2462306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2562306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2662306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2762306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 2862306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2962306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3062306a36Sopenharmony_ci * SOFTWARE. 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#ifndef IB_SRP_H 3462306a36Sopenharmony_ci#define IB_SRP_H 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#include <linux/types.h> 3762306a36Sopenharmony_ci#include <linux/list.h> 3862306a36Sopenharmony_ci#include <linux/mutex.h> 3962306a36Sopenharmony_ci#include <linux/scatterlist.h> 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#include <scsi/scsi_host.h> 4262306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h> 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 4562306a36Sopenharmony_ci#include <rdma/ib_sa.h> 4662306a36Sopenharmony_ci#include <rdma/ib_cm.h> 4762306a36Sopenharmony_ci#include <rdma/rdma_cm.h> 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cienum { 5062306a36Sopenharmony_ci SRP_PATH_REC_TIMEOUT_MS = 1000, 5162306a36Sopenharmony_ci SRP_ABORT_TIMEOUT_MS = 5000, 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci SRP_PORT_REDIRECT = 1, 5462306a36Sopenharmony_ci SRP_DLID_REDIRECT = 2, 5562306a36Sopenharmony_ci SRP_STALE_CONN = 3, 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci SRP_DEF_SG_TABLESIZE = 12, 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci SRP_DEFAULT_QUEUE_SIZE = 1 << 6, 6062306a36Sopenharmony_ci SRP_RSP_SQ_SIZE = 1, 6162306a36Sopenharmony_ci SRP_TSK_MGMT_SQ_SIZE = 1, 6262306a36Sopenharmony_ci SRP_DEFAULT_CMD_SQ_SIZE = SRP_DEFAULT_QUEUE_SIZE - SRP_RSP_SQ_SIZE - 6362306a36Sopenharmony_ci SRP_TSK_MGMT_SQ_SIZE, 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci SRP_MAX_PAGES_PER_MR = 512, 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci SRP_MAX_ADD_CDB_LEN = 16, 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci SRP_MAX_IMM_SGE = 2, 7062306a36Sopenharmony_ci SRP_MAX_SGE = SRP_MAX_IMM_SGE + 1, 7162306a36Sopenharmony_ci /* 7262306a36Sopenharmony_ci * Choose the immediate data offset such that a 32 byte CDB still fits. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_ci SRP_IMM_DATA_OFFSET = sizeof(struct srp_cmd) + 7562306a36Sopenharmony_ci SRP_MAX_ADD_CDB_LEN + 7662306a36Sopenharmony_ci sizeof(struct srp_imm_buf), 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cienum { 8062306a36Sopenharmony_ci SRP_TAG_NO_REQ = ~0U, 8162306a36Sopenharmony_ci SRP_TAG_TSK_MGMT = BIT(31), 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cienum srp_target_state { 8562306a36Sopenharmony_ci SRP_TARGET_SCANNING, 8662306a36Sopenharmony_ci SRP_TARGET_LIVE, 8762306a36Sopenharmony_ci SRP_TARGET_REMOVED, 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cienum srp_iu_type { 9162306a36Sopenharmony_ci SRP_IU_CMD, 9262306a36Sopenharmony_ci SRP_IU_TSK_MGMT, 9362306a36Sopenharmony_ci SRP_IU_RSP, 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* 9762306a36Sopenharmony_ci * RDMA adapter in the initiator system. 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * @dev_list: List of RDMA ports associated with this RDMA adapter (srp_host). 10062306a36Sopenharmony_ci * @mr_page_mask: HCA memory registration page mask. 10162306a36Sopenharmony_ci * @mr_page_size: HCA memory registration page size. 10262306a36Sopenharmony_ci * @mr_max_size: Maximum size in bytes of a single FR registration request. 10362306a36Sopenharmony_ci */ 10462306a36Sopenharmony_cistruct srp_device { 10562306a36Sopenharmony_ci struct list_head dev_list; 10662306a36Sopenharmony_ci struct ib_device *dev; 10762306a36Sopenharmony_ci struct ib_pd *pd; 10862306a36Sopenharmony_ci u32 global_rkey; 10962306a36Sopenharmony_ci u64 mr_page_mask; 11062306a36Sopenharmony_ci int mr_page_size; 11162306a36Sopenharmony_ci int mr_max_size; 11262306a36Sopenharmony_ci int max_pages_per_mr; 11362306a36Sopenharmony_ci bool has_fr; 11462306a36Sopenharmony_ci bool use_fast_reg; 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci/* 11862306a36Sopenharmony_ci * One port of an RDMA adapter in the initiator system. 11962306a36Sopenharmony_ci * 12062306a36Sopenharmony_ci * @target_list: List of connected target ports (struct srp_target_port). 12162306a36Sopenharmony_ci * @target_lock: Protects @target_list. 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_cistruct srp_host { 12462306a36Sopenharmony_ci struct srp_device *srp_dev; 12562306a36Sopenharmony_ci u32 port; 12662306a36Sopenharmony_ci struct device dev; 12762306a36Sopenharmony_ci struct list_head target_list; 12862306a36Sopenharmony_ci spinlock_t target_lock; 12962306a36Sopenharmony_ci struct list_head list; 13062306a36Sopenharmony_ci struct mutex add_target_mutex; 13162306a36Sopenharmony_ci}; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct srp_request { 13462306a36Sopenharmony_ci struct scsi_cmnd *scmnd; 13562306a36Sopenharmony_ci struct srp_iu *cmd; 13662306a36Sopenharmony_ci struct srp_fr_desc **fr_list; 13762306a36Sopenharmony_ci struct srp_direct_buf *indirect_desc; 13862306a36Sopenharmony_ci dma_addr_t indirect_dma_addr; 13962306a36Sopenharmony_ci short nmdesc; 14062306a36Sopenharmony_ci struct ib_cqe reg_cqe; 14162306a36Sopenharmony_ci}; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/** 14462306a36Sopenharmony_ci * struct srp_rdma_ch 14562306a36Sopenharmony_ci * @comp_vector: Completion vector used by this RDMA channel. 14662306a36Sopenharmony_ci * @max_it_iu_len: Maximum initiator-to-target information unit length. 14762306a36Sopenharmony_ci * @max_ti_iu_len: Maximum target-to-initiator information unit length. 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_cistruct srp_rdma_ch { 15062306a36Sopenharmony_ci /* These are RW in the hot path, and commonly used together */ 15162306a36Sopenharmony_ci struct list_head free_tx; 15262306a36Sopenharmony_ci spinlock_t lock; 15362306a36Sopenharmony_ci s32 req_lim; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci /* These are read-only in the hot path */ 15662306a36Sopenharmony_ci struct srp_target_port *target ____cacheline_aligned_in_smp; 15762306a36Sopenharmony_ci struct ib_cq *send_cq; 15862306a36Sopenharmony_ci struct ib_cq *recv_cq; 15962306a36Sopenharmony_ci struct ib_qp *qp; 16062306a36Sopenharmony_ci struct srp_fr_pool *fr_pool; 16162306a36Sopenharmony_ci uint32_t max_it_iu_len; 16262306a36Sopenharmony_ci uint32_t max_ti_iu_len; 16362306a36Sopenharmony_ci u8 max_imm_sge; 16462306a36Sopenharmony_ci bool use_imm_data; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* Everything above this point is used in the hot path of 16762306a36Sopenharmony_ci * command processing. Try to keep them packed into cachelines. 16862306a36Sopenharmony_ci */ 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci struct completion done; 17162306a36Sopenharmony_ci int status; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci union { 17462306a36Sopenharmony_ci struct ib_cm { 17562306a36Sopenharmony_ci struct sa_path_rec path; 17662306a36Sopenharmony_ci struct ib_sa_query *path_query; 17762306a36Sopenharmony_ci int path_query_id; 17862306a36Sopenharmony_ci struct ib_cm_id *cm_id; 17962306a36Sopenharmony_ci } ib_cm; 18062306a36Sopenharmony_ci struct rdma_cm { 18162306a36Sopenharmony_ci struct rdma_cm_id *cm_id; 18262306a36Sopenharmony_ci } rdma_cm; 18362306a36Sopenharmony_ci }; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci struct srp_iu **tx_ring; 18662306a36Sopenharmony_ci struct srp_iu **rx_ring; 18762306a36Sopenharmony_ci int comp_vector; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci u64 tsk_mgmt_tag; 19062306a36Sopenharmony_ci struct completion tsk_mgmt_done; 19162306a36Sopenharmony_ci u8 tsk_mgmt_status; 19262306a36Sopenharmony_ci bool connected; 19362306a36Sopenharmony_ci}; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci/** 19662306a36Sopenharmony_ci * struct srp_target_port - RDMA port in the SRP target system 19762306a36Sopenharmony_ci * @comp_vector: Completion vector used by the first RDMA channel created for 19862306a36Sopenharmony_ci * this target port. 19962306a36Sopenharmony_ci */ 20062306a36Sopenharmony_cistruct srp_target_port { 20162306a36Sopenharmony_ci /* read and written in the hot path */ 20262306a36Sopenharmony_ci spinlock_t lock; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci /* read only in the hot path */ 20562306a36Sopenharmony_ci u32 global_rkey; 20662306a36Sopenharmony_ci struct srp_rdma_ch *ch; 20762306a36Sopenharmony_ci struct net *net; 20862306a36Sopenharmony_ci u32 ch_count; 20962306a36Sopenharmony_ci u32 lkey; 21062306a36Sopenharmony_ci enum srp_target_state state; 21162306a36Sopenharmony_ci uint32_t max_it_iu_size; 21262306a36Sopenharmony_ci unsigned int cmd_sg_cnt; 21362306a36Sopenharmony_ci unsigned int indirect_size; 21462306a36Sopenharmony_ci bool allow_ext_sg; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* other member variables */ 21762306a36Sopenharmony_ci union ib_gid sgid; 21862306a36Sopenharmony_ci __be64 id_ext; 21962306a36Sopenharmony_ci __be64 ioc_guid; 22062306a36Sopenharmony_ci __be64 initiator_ext; 22162306a36Sopenharmony_ci u16 io_class; 22262306a36Sopenharmony_ci struct srp_host *srp_host; 22362306a36Sopenharmony_ci struct Scsi_Host *scsi_host; 22462306a36Sopenharmony_ci struct srp_rport *rport; 22562306a36Sopenharmony_ci char target_name[32]; 22662306a36Sopenharmony_ci unsigned int scsi_id; 22762306a36Sopenharmony_ci unsigned int sg_tablesize; 22862306a36Sopenharmony_ci unsigned int target_can_queue; 22962306a36Sopenharmony_ci int mr_pool_size; 23062306a36Sopenharmony_ci int mr_per_cmd; 23162306a36Sopenharmony_ci int queue_size; 23262306a36Sopenharmony_ci int comp_vector; 23362306a36Sopenharmony_ci int tl_retry_count; 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci bool using_rdma_cm; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci union { 23862306a36Sopenharmony_ci struct { 23962306a36Sopenharmony_ci __be64 service_id; 24062306a36Sopenharmony_ci union ib_gid orig_dgid; 24162306a36Sopenharmony_ci __be16 pkey; 24262306a36Sopenharmony_ci } ib_cm; 24362306a36Sopenharmony_ci struct { 24462306a36Sopenharmony_ci union { 24562306a36Sopenharmony_ci struct sockaddr_in ip4; 24662306a36Sopenharmony_ci struct sockaddr_in6 ip6; 24762306a36Sopenharmony_ci struct sockaddr sa; 24862306a36Sopenharmony_ci struct sockaddr_storage ss; 24962306a36Sopenharmony_ci } src; 25062306a36Sopenharmony_ci union { 25162306a36Sopenharmony_ci struct sockaddr_in ip4; 25262306a36Sopenharmony_ci struct sockaddr_in6 ip6; 25362306a36Sopenharmony_ci struct sockaddr sa; 25462306a36Sopenharmony_ci struct sockaddr_storage ss; 25562306a36Sopenharmony_ci } dst; 25662306a36Sopenharmony_ci bool src_specified; 25762306a36Sopenharmony_ci } rdma_cm; 25862306a36Sopenharmony_ci }; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci u32 rq_tmo_jiffies; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci int zero_req_lim; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci struct work_struct tl_err_work; 26562306a36Sopenharmony_ci struct work_struct remove_work; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci struct list_head list; 26862306a36Sopenharmony_ci bool qp_in_error; 26962306a36Sopenharmony_ci}; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistruct srp_iu { 27262306a36Sopenharmony_ci struct list_head list; 27362306a36Sopenharmony_ci u64 dma; 27462306a36Sopenharmony_ci void *buf; 27562306a36Sopenharmony_ci size_t size; 27662306a36Sopenharmony_ci enum dma_data_direction direction; 27762306a36Sopenharmony_ci u32 num_sge; 27862306a36Sopenharmony_ci struct ib_sge sge[SRP_MAX_SGE]; 27962306a36Sopenharmony_ci struct ib_cqe cqe; 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci/** 28362306a36Sopenharmony_ci * struct srp_fr_desc - fast registration work request arguments 28462306a36Sopenharmony_ci * @entry: Entry in srp_fr_pool.free_list. 28562306a36Sopenharmony_ci * @mr: Memory region. 28662306a36Sopenharmony_ci * @frpl: Fast registration page list. 28762306a36Sopenharmony_ci */ 28862306a36Sopenharmony_cistruct srp_fr_desc { 28962306a36Sopenharmony_ci struct list_head entry; 29062306a36Sopenharmony_ci struct ib_mr *mr; 29162306a36Sopenharmony_ci}; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci/** 29462306a36Sopenharmony_ci * struct srp_fr_pool - pool of fast registration descriptors 29562306a36Sopenharmony_ci * 29662306a36Sopenharmony_ci * An entry is available for allocation if and only if it occurs in @free_list. 29762306a36Sopenharmony_ci * 29862306a36Sopenharmony_ci * @size: Number of descriptors in this pool. 29962306a36Sopenharmony_ci * @max_page_list_len: Maximum fast registration work request page list length. 30062306a36Sopenharmony_ci * @lock: Protects free_list. 30162306a36Sopenharmony_ci * @free_list: List of free descriptors. 30262306a36Sopenharmony_ci * @desc: Fast registration descriptor pool. 30362306a36Sopenharmony_ci */ 30462306a36Sopenharmony_cistruct srp_fr_pool { 30562306a36Sopenharmony_ci int size; 30662306a36Sopenharmony_ci int max_page_list_len; 30762306a36Sopenharmony_ci spinlock_t lock; 30862306a36Sopenharmony_ci struct list_head free_list; 30962306a36Sopenharmony_ci struct srp_fr_desc desc[]; 31062306a36Sopenharmony_ci}; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/** 31362306a36Sopenharmony_ci * struct srp_map_state - per-request DMA memory mapping state 31462306a36Sopenharmony_ci * @desc: Pointer to the element of the SRP buffer descriptor array 31562306a36Sopenharmony_ci * that is being filled in. 31662306a36Sopenharmony_ci * @pages: Array with DMA addresses of pages being considered for 31762306a36Sopenharmony_ci * memory registration. 31862306a36Sopenharmony_ci * @base_dma_addr: DMA address of the first page that has not yet been mapped. 31962306a36Sopenharmony_ci * @dma_len: Number of bytes that will be registered with the next FR 32062306a36Sopenharmony_ci * memory registration call. 32162306a36Sopenharmony_ci * @total_len: Total number of bytes in the sg-list being mapped. 32262306a36Sopenharmony_ci * @npages: Number of page addresses in the pages[] array. 32362306a36Sopenharmony_ci * @nmdesc: Number of FR memory descriptors used for mapping. 32462306a36Sopenharmony_ci * @ndesc: Number of SRP buffer descriptors that have been filled in. 32562306a36Sopenharmony_ci */ 32662306a36Sopenharmony_cistruct srp_map_state { 32762306a36Sopenharmony_ci union { 32862306a36Sopenharmony_ci struct { 32962306a36Sopenharmony_ci struct srp_fr_desc **next; 33062306a36Sopenharmony_ci struct srp_fr_desc **end; 33162306a36Sopenharmony_ci } fr; 33262306a36Sopenharmony_ci struct { 33362306a36Sopenharmony_ci void **next; 33462306a36Sopenharmony_ci void **end; 33562306a36Sopenharmony_ci } gen; 33662306a36Sopenharmony_ci }; 33762306a36Sopenharmony_ci struct srp_direct_buf *desc; 33862306a36Sopenharmony_ci union { 33962306a36Sopenharmony_ci u64 *pages; 34062306a36Sopenharmony_ci struct scatterlist *sg; 34162306a36Sopenharmony_ci }; 34262306a36Sopenharmony_ci dma_addr_t base_dma_addr; 34362306a36Sopenharmony_ci u32 dma_len; 34462306a36Sopenharmony_ci u32 total_len; 34562306a36Sopenharmony_ci unsigned int npages; 34662306a36Sopenharmony_ci unsigned int nmdesc; 34762306a36Sopenharmony_ci unsigned int ndesc; 34862306a36Sopenharmony_ci}; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci#endif /* IB_SRP_H */ 351