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