18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2005 Cisco Systems. All rights reserved. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 58c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 68c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 78c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the 88c2ecf20Sopenharmony_ci * OpenIB.org BSD license below: 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or 118c2ecf20Sopenharmony_ci * without modification, are permitted provided that the following 128c2ecf20Sopenharmony_ci * conditions are met: 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * - Redistributions of source code must retain the above 158c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 168c2ecf20Sopenharmony_ci * disclaimer. 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * - Redistributions in binary form must reproduce the above 198c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 208c2ecf20Sopenharmony_ci * disclaimer in the documentation and/or other materials 218c2ecf20Sopenharmony_ci * provided with the distribution. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 248c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 258c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 268c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 278c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 288c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 298c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 308c2ecf20Sopenharmony_ci * SOFTWARE. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#ifndef IB_SRP_H 348c2ecf20Sopenharmony_ci#define IB_SRP_H 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#include <linux/types.h> 378c2ecf20Sopenharmony_ci#include <linux/list.h> 388c2ecf20Sopenharmony_ci#include <linux/mutex.h> 398c2ecf20Sopenharmony_ci#include <linux/scatterlist.h> 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h> 428c2ecf20Sopenharmony_ci#include <scsi/scsi_cmnd.h> 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#include <rdma/ib_verbs.h> 458c2ecf20Sopenharmony_ci#include <rdma/ib_sa.h> 468c2ecf20Sopenharmony_ci#include <rdma/ib_cm.h> 478c2ecf20Sopenharmony_ci#include <rdma/rdma_cm.h> 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cienum { 508c2ecf20Sopenharmony_ci SRP_PATH_REC_TIMEOUT_MS = 1000, 518c2ecf20Sopenharmony_ci SRP_ABORT_TIMEOUT_MS = 5000, 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci SRP_PORT_REDIRECT = 1, 548c2ecf20Sopenharmony_ci SRP_DLID_REDIRECT = 2, 558c2ecf20Sopenharmony_ci SRP_STALE_CONN = 3, 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci SRP_DEF_SG_TABLESIZE = 12, 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci SRP_DEFAULT_QUEUE_SIZE = 1 << 6, 608c2ecf20Sopenharmony_ci SRP_RSP_SQ_SIZE = 1, 618c2ecf20Sopenharmony_ci SRP_TSK_MGMT_SQ_SIZE = 1, 628c2ecf20Sopenharmony_ci SRP_DEFAULT_CMD_SQ_SIZE = SRP_DEFAULT_QUEUE_SIZE - SRP_RSP_SQ_SIZE - 638c2ecf20Sopenharmony_ci SRP_TSK_MGMT_SQ_SIZE, 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci SRP_MAX_PAGES_PER_MR = 512, 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci SRP_MAX_ADD_CDB_LEN = 16, 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci SRP_MAX_IMM_SGE = 2, 708c2ecf20Sopenharmony_ci SRP_MAX_SGE = SRP_MAX_IMM_SGE + 1, 718c2ecf20Sopenharmony_ci /* 728c2ecf20Sopenharmony_ci * Choose the immediate data offset such that a 32 byte CDB still fits. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci SRP_IMM_DATA_OFFSET = sizeof(struct srp_cmd) + 758c2ecf20Sopenharmony_ci SRP_MAX_ADD_CDB_LEN + 768c2ecf20Sopenharmony_ci sizeof(struct srp_imm_buf), 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cienum { 808c2ecf20Sopenharmony_ci SRP_TAG_NO_REQ = ~0U, 818c2ecf20Sopenharmony_ci SRP_TAG_TSK_MGMT = BIT(31), 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cienum srp_target_state { 858c2ecf20Sopenharmony_ci SRP_TARGET_SCANNING, 868c2ecf20Sopenharmony_ci SRP_TARGET_LIVE, 878c2ecf20Sopenharmony_ci SRP_TARGET_REMOVED, 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cienum srp_iu_type { 918c2ecf20Sopenharmony_ci SRP_IU_CMD, 928c2ecf20Sopenharmony_ci SRP_IU_TSK_MGMT, 938c2ecf20Sopenharmony_ci SRP_IU_RSP, 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* 978c2ecf20Sopenharmony_ci * @mr_page_mask: HCA memory registration page mask. 988c2ecf20Sopenharmony_ci * @mr_page_size: HCA memory registration page size. 998c2ecf20Sopenharmony_ci * @mr_max_size: Maximum size in bytes of a single FR registration request. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_cistruct srp_device { 1028c2ecf20Sopenharmony_ci struct list_head dev_list; 1038c2ecf20Sopenharmony_ci struct ib_device *dev; 1048c2ecf20Sopenharmony_ci struct ib_pd *pd; 1058c2ecf20Sopenharmony_ci u32 global_rkey; 1068c2ecf20Sopenharmony_ci u64 mr_page_mask; 1078c2ecf20Sopenharmony_ci int mr_page_size; 1088c2ecf20Sopenharmony_ci int mr_max_size; 1098c2ecf20Sopenharmony_ci int max_pages_per_mr; 1108c2ecf20Sopenharmony_ci bool has_fr; 1118c2ecf20Sopenharmony_ci bool use_fast_reg; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistruct srp_host { 1158c2ecf20Sopenharmony_ci struct srp_device *srp_dev; 1168c2ecf20Sopenharmony_ci u8 port; 1178c2ecf20Sopenharmony_ci struct device dev; 1188c2ecf20Sopenharmony_ci struct list_head target_list; 1198c2ecf20Sopenharmony_ci spinlock_t target_lock; 1208c2ecf20Sopenharmony_ci struct completion released; 1218c2ecf20Sopenharmony_ci struct list_head list; 1228c2ecf20Sopenharmony_ci struct mutex add_target_mutex; 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistruct srp_request { 1268c2ecf20Sopenharmony_ci struct scsi_cmnd *scmnd; 1278c2ecf20Sopenharmony_ci struct srp_iu *cmd; 1288c2ecf20Sopenharmony_ci struct srp_fr_desc **fr_list; 1298c2ecf20Sopenharmony_ci struct srp_direct_buf *indirect_desc; 1308c2ecf20Sopenharmony_ci dma_addr_t indirect_dma_addr; 1318c2ecf20Sopenharmony_ci short nmdesc; 1328c2ecf20Sopenharmony_ci struct ib_cqe reg_cqe; 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/** 1368c2ecf20Sopenharmony_ci * struct srp_rdma_ch 1378c2ecf20Sopenharmony_ci * @comp_vector: Completion vector used by this RDMA channel. 1388c2ecf20Sopenharmony_ci * @max_it_iu_len: Maximum initiator-to-target information unit length. 1398c2ecf20Sopenharmony_ci * @max_ti_iu_len: Maximum target-to-initiator information unit length. 1408c2ecf20Sopenharmony_ci */ 1418c2ecf20Sopenharmony_cistruct srp_rdma_ch { 1428c2ecf20Sopenharmony_ci /* These are RW in the hot path, and commonly used together */ 1438c2ecf20Sopenharmony_ci struct list_head free_tx; 1448c2ecf20Sopenharmony_ci spinlock_t lock; 1458c2ecf20Sopenharmony_ci s32 req_lim; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci /* These are read-only in the hot path */ 1488c2ecf20Sopenharmony_ci struct srp_target_port *target ____cacheline_aligned_in_smp; 1498c2ecf20Sopenharmony_ci struct ib_cq *send_cq; 1508c2ecf20Sopenharmony_ci struct ib_cq *recv_cq; 1518c2ecf20Sopenharmony_ci struct ib_qp *qp; 1528c2ecf20Sopenharmony_ci struct srp_fr_pool *fr_pool; 1538c2ecf20Sopenharmony_ci uint32_t max_it_iu_len; 1548c2ecf20Sopenharmony_ci uint32_t max_ti_iu_len; 1558c2ecf20Sopenharmony_ci u8 max_imm_sge; 1568c2ecf20Sopenharmony_ci bool use_imm_data; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci /* Everything above this point is used in the hot path of 1598c2ecf20Sopenharmony_ci * command processing. Try to keep them packed into cachelines. 1608c2ecf20Sopenharmony_ci */ 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci struct completion done; 1638c2ecf20Sopenharmony_ci int status; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci union { 1668c2ecf20Sopenharmony_ci struct ib_cm { 1678c2ecf20Sopenharmony_ci struct sa_path_rec path; 1688c2ecf20Sopenharmony_ci struct ib_sa_query *path_query; 1698c2ecf20Sopenharmony_ci int path_query_id; 1708c2ecf20Sopenharmony_ci struct ib_cm_id *cm_id; 1718c2ecf20Sopenharmony_ci } ib_cm; 1728c2ecf20Sopenharmony_ci struct rdma_cm { 1738c2ecf20Sopenharmony_ci struct rdma_cm_id *cm_id; 1748c2ecf20Sopenharmony_ci } rdma_cm; 1758c2ecf20Sopenharmony_ci }; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci struct srp_iu **tx_ring; 1788c2ecf20Sopenharmony_ci struct srp_iu **rx_ring; 1798c2ecf20Sopenharmony_ci int comp_vector; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci u64 tsk_mgmt_tag; 1828c2ecf20Sopenharmony_ci struct completion tsk_mgmt_done; 1838c2ecf20Sopenharmony_ci u8 tsk_mgmt_status; 1848c2ecf20Sopenharmony_ci bool connected; 1858c2ecf20Sopenharmony_ci}; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/** 1888c2ecf20Sopenharmony_ci * struct srp_target_port 1898c2ecf20Sopenharmony_ci * @comp_vector: Completion vector used by the first RDMA channel created for 1908c2ecf20Sopenharmony_ci * this target port. 1918c2ecf20Sopenharmony_ci */ 1928c2ecf20Sopenharmony_cistruct srp_target_port { 1938c2ecf20Sopenharmony_ci /* read and written in the hot path */ 1948c2ecf20Sopenharmony_ci spinlock_t lock; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci /* read only in the hot path */ 1978c2ecf20Sopenharmony_ci u32 global_rkey; 1988c2ecf20Sopenharmony_ci struct srp_rdma_ch *ch; 1998c2ecf20Sopenharmony_ci struct net *net; 2008c2ecf20Sopenharmony_ci u32 ch_count; 2018c2ecf20Sopenharmony_ci u32 lkey; 2028c2ecf20Sopenharmony_ci enum srp_target_state state; 2038c2ecf20Sopenharmony_ci uint32_t max_it_iu_size; 2048c2ecf20Sopenharmony_ci unsigned int cmd_sg_cnt; 2058c2ecf20Sopenharmony_ci unsigned int indirect_size; 2068c2ecf20Sopenharmony_ci bool allow_ext_sg; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci /* other member variables */ 2098c2ecf20Sopenharmony_ci union ib_gid sgid; 2108c2ecf20Sopenharmony_ci __be64 id_ext; 2118c2ecf20Sopenharmony_ci __be64 ioc_guid; 2128c2ecf20Sopenharmony_ci __be64 initiator_ext; 2138c2ecf20Sopenharmony_ci u16 io_class; 2148c2ecf20Sopenharmony_ci struct srp_host *srp_host; 2158c2ecf20Sopenharmony_ci struct Scsi_Host *scsi_host; 2168c2ecf20Sopenharmony_ci struct srp_rport *rport; 2178c2ecf20Sopenharmony_ci char target_name[32]; 2188c2ecf20Sopenharmony_ci unsigned int scsi_id; 2198c2ecf20Sopenharmony_ci unsigned int sg_tablesize; 2208c2ecf20Sopenharmony_ci unsigned int target_can_queue; 2218c2ecf20Sopenharmony_ci int mr_pool_size; 2228c2ecf20Sopenharmony_ci int mr_per_cmd; 2238c2ecf20Sopenharmony_ci int queue_size; 2248c2ecf20Sopenharmony_ci int comp_vector; 2258c2ecf20Sopenharmony_ci int tl_retry_count; 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci bool using_rdma_cm; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci union { 2308c2ecf20Sopenharmony_ci struct { 2318c2ecf20Sopenharmony_ci __be64 service_id; 2328c2ecf20Sopenharmony_ci union ib_gid orig_dgid; 2338c2ecf20Sopenharmony_ci __be16 pkey; 2348c2ecf20Sopenharmony_ci } ib_cm; 2358c2ecf20Sopenharmony_ci struct { 2368c2ecf20Sopenharmony_ci union { 2378c2ecf20Sopenharmony_ci struct sockaddr_in ip4; 2388c2ecf20Sopenharmony_ci struct sockaddr_in6 ip6; 2398c2ecf20Sopenharmony_ci struct sockaddr sa; 2408c2ecf20Sopenharmony_ci struct sockaddr_storage ss; 2418c2ecf20Sopenharmony_ci } src; 2428c2ecf20Sopenharmony_ci union { 2438c2ecf20Sopenharmony_ci struct sockaddr_in ip4; 2448c2ecf20Sopenharmony_ci struct sockaddr_in6 ip6; 2458c2ecf20Sopenharmony_ci struct sockaddr sa; 2468c2ecf20Sopenharmony_ci struct sockaddr_storage ss; 2478c2ecf20Sopenharmony_ci } dst; 2488c2ecf20Sopenharmony_ci bool src_specified; 2498c2ecf20Sopenharmony_ci } rdma_cm; 2508c2ecf20Sopenharmony_ci }; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci u32 rq_tmo_jiffies; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci int zero_req_lim; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci struct work_struct tl_err_work; 2578c2ecf20Sopenharmony_ci struct work_struct remove_work; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci struct list_head list; 2608c2ecf20Sopenharmony_ci bool qp_in_error; 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistruct srp_iu { 2648c2ecf20Sopenharmony_ci struct list_head list; 2658c2ecf20Sopenharmony_ci u64 dma; 2668c2ecf20Sopenharmony_ci void *buf; 2678c2ecf20Sopenharmony_ci size_t size; 2688c2ecf20Sopenharmony_ci enum dma_data_direction direction; 2698c2ecf20Sopenharmony_ci u32 num_sge; 2708c2ecf20Sopenharmony_ci struct ib_sge sge[SRP_MAX_SGE]; 2718c2ecf20Sopenharmony_ci struct ib_cqe cqe; 2728c2ecf20Sopenharmony_ci}; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci/** 2758c2ecf20Sopenharmony_ci * struct srp_fr_desc - fast registration work request arguments 2768c2ecf20Sopenharmony_ci * @entry: Entry in srp_fr_pool.free_list. 2778c2ecf20Sopenharmony_ci * @mr: Memory region. 2788c2ecf20Sopenharmony_ci * @frpl: Fast registration page list. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_cistruct srp_fr_desc { 2818c2ecf20Sopenharmony_ci struct list_head entry; 2828c2ecf20Sopenharmony_ci struct ib_mr *mr; 2838c2ecf20Sopenharmony_ci}; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci/** 2868c2ecf20Sopenharmony_ci * struct srp_fr_pool - pool of fast registration descriptors 2878c2ecf20Sopenharmony_ci * 2888c2ecf20Sopenharmony_ci * An entry is available for allocation if and only if it occurs in @free_list. 2898c2ecf20Sopenharmony_ci * 2908c2ecf20Sopenharmony_ci * @size: Number of descriptors in this pool. 2918c2ecf20Sopenharmony_ci * @max_page_list_len: Maximum fast registration work request page list length. 2928c2ecf20Sopenharmony_ci * @lock: Protects free_list. 2938c2ecf20Sopenharmony_ci * @free_list: List of free descriptors. 2948c2ecf20Sopenharmony_ci * @desc: Fast registration descriptor pool. 2958c2ecf20Sopenharmony_ci */ 2968c2ecf20Sopenharmony_cistruct srp_fr_pool { 2978c2ecf20Sopenharmony_ci int size; 2988c2ecf20Sopenharmony_ci int max_page_list_len; 2998c2ecf20Sopenharmony_ci spinlock_t lock; 3008c2ecf20Sopenharmony_ci struct list_head free_list; 3018c2ecf20Sopenharmony_ci struct srp_fr_desc desc[]; 3028c2ecf20Sopenharmony_ci}; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci/** 3058c2ecf20Sopenharmony_ci * struct srp_map_state - per-request DMA memory mapping state 3068c2ecf20Sopenharmony_ci * @desc: Pointer to the element of the SRP buffer descriptor array 3078c2ecf20Sopenharmony_ci * that is being filled in. 3088c2ecf20Sopenharmony_ci * @pages: Array with DMA addresses of pages being considered for 3098c2ecf20Sopenharmony_ci * memory registration. 3108c2ecf20Sopenharmony_ci * @base_dma_addr: DMA address of the first page that has not yet been mapped. 3118c2ecf20Sopenharmony_ci * @dma_len: Number of bytes that will be registered with the next FR 3128c2ecf20Sopenharmony_ci * memory registration call. 3138c2ecf20Sopenharmony_ci * @total_len: Total number of bytes in the sg-list being mapped. 3148c2ecf20Sopenharmony_ci * @npages: Number of page addresses in the pages[] array. 3158c2ecf20Sopenharmony_ci * @nmdesc: Number of FR memory descriptors used for mapping. 3168c2ecf20Sopenharmony_ci * @ndesc: Number of SRP buffer descriptors that have been filled in. 3178c2ecf20Sopenharmony_ci */ 3188c2ecf20Sopenharmony_cistruct srp_map_state { 3198c2ecf20Sopenharmony_ci union { 3208c2ecf20Sopenharmony_ci struct { 3218c2ecf20Sopenharmony_ci struct srp_fr_desc **next; 3228c2ecf20Sopenharmony_ci struct srp_fr_desc **end; 3238c2ecf20Sopenharmony_ci } fr; 3248c2ecf20Sopenharmony_ci struct { 3258c2ecf20Sopenharmony_ci void **next; 3268c2ecf20Sopenharmony_ci void **end; 3278c2ecf20Sopenharmony_ci } gen; 3288c2ecf20Sopenharmony_ci }; 3298c2ecf20Sopenharmony_ci struct srp_direct_buf *desc; 3308c2ecf20Sopenharmony_ci union { 3318c2ecf20Sopenharmony_ci u64 *pages; 3328c2ecf20Sopenharmony_ci struct scatterlist *sg; 3338c2ecf20Sopenharmony_ci }; 3348c2ecf20Sopenharmony_ci dma_addr_t base_dma_addr; 3358c2ecf20Sopenharmony_ci u32 dma_len; 3368c2ecf20Sopenharmony_ci u32 total_len; 3378c2ecf20Sopenharmony_ci unsigned int npages; 3388c2ecf20Sopenharmony_ci unsigned int nmdesc; 3398c2ecf20Sopenharmony_ci unsigned int ndesc; 3408c2ecf20Sopenharmony_ci}; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci#endif /* IB_SRP_H */ 343