xref: /freebsd-src/sys/dev/iser/icl_iser.h (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
14814a0a4SEdward Tomasz Napierala /*-
24814a0a4SEdward Tomasz Napierala  * Copyright (c) 2015, Mellanox Technologies, Inc. All rights reserved.
34814a0a4SEdward Tomasz Napierala  *
44814a0a4SEdward Tomasz Napierala  * Redistribution and use in source and binary forms, with or without
54814a0a4SEdward Tomasz Napierala  * modification, are permitted provided that the following conditions
64814a0a4SEdward Tomasz Napierala  * are met:
74814a0a4SEdward Tomasz Napierala  * 1. Redistributions of source code must retain the above copyright
84814a0a4SEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer.
94814a0a4SEdward Tomasz Napierala  * 2. Redistributions in binary form must reproduce the above copyright
104814a0a4SEdward Tomasz Napierala  *    notice, this list of conditions and the following disclaimer in the
114814a0a4SEdward Tomasz Napierala  *    documentation and/or other materials provided with the distribution.
124814a0a4SEdward Tomasz Napierala  *
134814a0a4SEdward Tomasz Napierala  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
144814a0a4SEdward Tomasz Napierala  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
154814a0a4SEdward Tomasz Napierala  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
164814a0a4SEdward Tomasz Napierala  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
174814a0a4SEdward Tomasz Napierala  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
184814a0a4SEdward Tomasz Napierala  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
194814a0a4SEdward Tomasz Napierala  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
204814a0a4SEdward Tomasz Napierala  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
214814a0a4SEdward Tomasz Napierala  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
224814a0a4SEdward Tomasz Napierala  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
234814a0a4SEdward Tomasz Napierala  * SUCH DAMAGE.
244814a0a4SEdward Tomasz Napierala  */
254814a0a4SEdward Tomasz Napierala 
264814a0a4SEdward Tomasz Napierala #ifndef ICL_ISER_H
274814a0a4SEdward Tomasz Napierala #define ICL_ISER_H
284814a0a4SEdward Tomasz Napierala 
294814a0a4SEdward Tomasz Napierala /*
304814a0a4SEdward Tomasz Napierala  * iSCSI Common Layer for RDMA.
314814a0a4SEdward Tomasz Napierala  */
324814a0a4SEdward Tomasz Napierala 
334814a0a4SEdward Tomasz Napierala #include <sys/param.h>
344814a0a4SEdward Tomasz Napierala #include <sys/capsicum.h>
354814a0a4SEdward Tomasz Napierala #include <sys/condvar.h>
364814a0a4SEdward Tomasz Napierala #include <sys/conf.h>
374814a0a4SEdward Tomasz Napierala #include <sys/file.h>
384814a0a4SEdward Tomasz Napierala #include <sys/kernel.h>
394814a0a4SEdward Tomasz Napierala #include <sys/kthread.h>
404814a0a4SEdward Tomasz Napierala #include <sys/lock.h>
414814a0a4SEdward Tomasz Napierala #include <sys/mbuf.h>
424814a0a4SEdward Tomasz Napierala #include <sys/mutex.h>
434814a0a4SEdward Tomasz Napierala #include <sys/module.h>
444814a0a4SEdward Tomasz Napierala #include <sys/protosw.h>
454814a0a4SEdward Tomasz Napierala #include <sys/socket.h>
464814a0a4SEdward Tomasz Napierala #include <sys/socketvar.h>
474814a0a4SEdward Tomasz Napierala #include <sys/sysctl.h>
484814a0a4SEdward Tomasz Napierala #include <sys/systm.h>
494814a0a4SEdward Tomasz Napierala #include <sys/sx.h>
504814a0a4SEdward Tomasz Napierala #include <sys/uio.h>
514814a0a4SEdward Tomasz Napierala #include <sys/taskqueue.h>
524814a0a4SEdward Tomasz Napierala #include <sys/bio.h>
534814a0a4SEdward Tomasz Napierala #include <vm/uma.h>
544814a0a4SEdward Tomasz Napierala #include <netinet/in.h>
554814a0a4SEdward Tomasz Napierala #include <netinet/tcp.h>
564814a0a4SEdward Tomasz Napierala #include <dev/iscsi/icl.h>
574814a0a4SEdward Tomasz Napierala #include <dev/iscsi/iscsi_proto.h>
584814a0a4SEdward Tomasz Napierala #include <icl_conn_if.h>
594814a0a4SEdward Tomasz Napierala #include <cam/cam.h>
604814a0a4SEdward Tomasz Napierala #include <cam/cam_ccb.h>
614814a0a4SEdward Tomasz Napierala #include <rdma/ib_verbs.h>
624814a0a4SEdward Tomasz Napierala #include <rdma/ib_fmr_pool.h>
634814a0a4SEdward Tomasz Napierala #include <rdma/rdma_cm.h>
644814a0a4SEdward Tomasz Napierala 
654814a0a4SEdward Tomasz Napierala 
664814a0a4SEdward Tomasz Napierala #define	ISER_DBG(X, ...)						\
674814a0a4SEdward Tomasz Napierala 	do {								\
684814a0a4SEdward Tomasz Napierala 		if (unlikely(iser_debug > 2))				\
694814a0a4SEdward Tomasz Napierala 			printf("DEBUG: %s: " X "\n",			\
704814a0a4SEdward Tomasz Napierala 				__func__, ## __VA_ARGS__);		\
714814a0a4SEdward Tomasz Napierala 	} while (0)
724814a0a4SEdward Tomasz Napierala 
734814a0a4SEdward Tomasz Napierala #define	ISER_INFO(X, ...)						\
744814a0a4SEdward Tomasz Napierala 	do {								\
754814a0a4SEdward Tomasz Napierala 		if (unlikely(iser_debug > 1))				\
764814a0a4SEdward Tomasz Napierala 			printf("INFO: %s: " X "\n",			\
774814a0a4SEdward Tomasz Napierala 				__func__, ## __VA_ARGS__);		\
784814a0a4SEdward Tomasz Napierala 	} while (0)
794814a0a4SEdward Tomasz Napierala 
804814a0a4SEdward Tomasz Napierala #define	ISER_WARN(X, ...)						\
814814a0a4SEdward Tomasz Napierala 	do {								\
824814a0a4SEdward Tomasz Napierala 		if (unlikely(iser_debug > 0)) {				\
834814a0a4SEdward Tomasz Napierala 			printf("WARNING: %s: " X "\n",			\
844814a0a4SEdward Tomasz Napierala 				__func__, ## __VA_ARGS__);		\
854814a0a4SEdward Tomasz Napierala 		}							\
864814a0a4SEdward Tomasz Napierala 	} while (0)
874814a0a4SEdward Tomasz Napierala 
884814a0a4SEdward Tomasz Napierala #define	ISER_ERR(X, ...) 						\
894814a0a4SEdward Tomasz Napierala 	printf("ERROR: %s: " X "\n", __func__, ## __VA_ARGS__)
904814a0a4SEdward Tomasz Napierala 
914814a0a4SEdward Tomasz Napierala #define ISER_VER			0x10
924814a0a4SEdward Tomasz Napierala #define ISER_WSV			0x08
934814a0a4SEdward Tomasz Napierala #define ISER_RSV			0x04
944814a0a4SEdward Tomasz Napierala 
954814a0a4SEdward Tomasz Napierala #define ISER_FASTREG_LI_WRID		0xffffffffffffffffULL
964814a0a4SEdward Tomasz Napierala #define ISER_BEACON_WRID		0xfffffffffffffffeULL
974814a0a4SEdward Tomasz Napierala 
984814a0a4SEdward Tomasz Napierala #define SHIFT_4K	12
994814a0a4SEdward Tomasz Napierala #define SIZE_4K	(1ULL << SHIFT_4K)
1004814a0a4SEdward Tomasz Napierala #define MASK_4K	(~(SIZE_4K-1))
1014814a0a4SEdward Tomasz Napierala 
1024814a0a4SEdward Tomasz Napierala /* support up to 512KB in one RDMA */
1034814a0a4SEdward Tomasz Napierala #define ISCSI_ISER_SG_TABLESIZE         (0x80000 >> SHIFT_4K)
1044814a0a4SEdward Tomasz Napierala #define ISER_DEF_XMIT_CMDS_MAX 256
1054814a0a4SEdward Tomasz Napierala 
1064814a0a4SEdward Tomasz Napierala /* the max RX (recv) WR supported by the iSER QP is defined by                 *
1074814a0a4SEdward Tomasz Napierala  * max_recv_wr = commands_max + recv_beacon                                    */
1084814a0a4SEdward Tomasz Napierala #define ISER_QP_MAX_RECV_DTOS  (ISER_DEF_XMIT_CMDS_MAX + 1)
1094814a0a4SEdward Tomasz Napierala #define ISER_MIN_POSTED_RX		(ISER_DEF_XMIT_CMDS_MAX >> 2)
1104814a0a4SEdward Tomasz Napierala 
1114814a0a4SEdward Tomasz Napierala /* QP settings */
1124814a0a4SEdward Tomasz Napierala /* Maximal bounds on received asynchronous PDUs */
1134814a0a4SEdward Tomasz Napierala #define ISER_MAX_RX_MISC_PDUS           4 /* NOOP_IN(2) , ASYNC_EVENT(2)   */
1144814a0a4SEdward Tomasz Napierala #define ISER_MAX_TX_MISC_PDUS           6 /* NOOP_OUT(2), TEXT(1), SCSI_TMFUNC(2), LOGOUT(1) */
1154814a0a4SEdward Tomasz Napierala 
1164814a0a4SEdward Tomasz Napierala /* the max TX (send) WR supported by the iSER QP is defined by                 *
1174814a0a4SEdward Tomasz Napierala  * max_send_wr = T * (1 + D) + C ; D is how many inflight dataouts we expect   *
1184814a0a4SEdward Tomasz Napierala  * to have at max for SCSI command. The tx posting & completion handling code  *
1194814a0a4SEdward Tomasz Napierala  * supports -EAGAIN scheme where tx is suspended till the QP has room for more *
1204814a0a4SEdward Tomasz Napierala  * send WR. D=8 comes from 64K/8K                                              */
1214814a0a4SEdward Tomasz Napierala 
1224814a0a4SEdward Tomasz Napierala #define ISER_INFLIGHT_DATAOUTS		8
1234814a0a4SEdward Tomasz Napierala 
1244814a0a4SEdward Tomasz Napierala /* the send_beacon increase the max_send_wr by 1  */
1254814a0a4SEdward Tomasz Napierala #define ISER_QP_MAX_REQ_DTOS		(ISER_DEF_XMIT_CMDS_MAX *    \
1264814a0a4SEdward Tomasz Napierala 					(1 + ISER_INFLIGHT_DATAOUTS) + \
1274814a0a4SEdward Tomasz Napierala 					ISER_MAX_TX_MISC_PDUS        + \
1284814a0a4SEdward Tomasz Napierala 					ISER_MAX_RX_MISC_PDUS + 1)
1294814a0a4SEdward Tomasz Napierala 
1304814a0a4SEdward Tomasz Napierala #define ISER_GET_MAX_XMIT_CMDS(send_wr) ((send_wr			\
1314814a0a4SEdward Tomasz Napierala 					 - ISER_MAX_TX_MISC_PDUS	\
1324814a0a4SEdward Tomasz Napierala 					 - ISER_MAX_RX_MISC_PDUS - 1) /	\
1334814a0a4SEdward Tomasz Napierala 					 (1 + ISER_INFLIGHT_DATAOUTS))
1344814a0a4SEdward Tomasz Napierala 
1354814a0a4SEdward Tomasz Napierala #define ISER_WC_BATCH_COUNT   16
1364814a0a4SEdward Tomasz Napierala #define ISER_SIGNAL_CMD_COUNT 32
1374814a0a4SEdward Tomasz Napierala 
1384814a0a4SEdward Tomasz Napierala /* Maximal QP's recommended per CQ. In case we use more QP's per CQ we might   *
1394814a0a4SEdward Tomasz Napierala  * encounter a CQ overrun state.                                               */
1404814a0a4SEdward Tomasz Napierala #define ISCSI_ISER_MAX_CONN	8
1414814a0a4SEdward Tomasz Napierala #define ISER_MAX_RX_LEN		(ISER_QP_MAX_RECV_DTOS * ISCSI_ISER_MAX_CONN)
1424814a0a4SEdward Tomasz Napierala #define ISER_MAX_TX_LEN		(ISER_QP_MAX_REQ_DTOS  * ISCSI_ISER_MAX_CONN)
1434814a0a4SEdward Tomasz Napierala #define ISER_MAX_CQ_LEN		(ISER_MAX_RX_LEN + ISER_MAX_TX_LEN + \
1444814a0a4SEdward Tomasz Napierala 				 ISCSI_ISER_MAX_CONN)
1454814a0a4SEdward Tomasz Napierala 
1464814a0a4SEdward Tomasz Napierala #define ISER_ZBVA_NOT_SUPPORTED                0x80
1474814a0a4SEdward Tomasz Napierala #define ISER_SEND_W_INV_NOT_SUPPORTED	0x40
1484814a0a4SEdward Tomasz Napierala 
14995c4a392SEdward Tomasz Napierala #define	ISCSI_DEF_MAX_RECV_SEG_LEN	8192
15095c4a392SEdward Tomasz Napierala #define	ISCSI_OPCODE_MASK		0x3f
15195c4a392SEdward Tomasz Napierala 
1524814a0a4SEdward Tomasz Napierala #define icl_to_iser_conn(ic) \
1534814a0a4SEdward Tomasz Napierala 	container_of(ic, struct iser_conn, icl_conn)
1544814a0a4SEdward Tomasz Napierala #define icl_to_iser_pdu(ip) \
1554814a0a4SEdward Tomasz Napierala 	container_of(ip, struct icl_iser_pdu, icl_pdu)
1564814a0a4SEdward Tomasz Napierala 
1574814a0a4SEdward Tomasz Napierala /**
1584814a0a4SEdward Tomasz Napierala  * struct iser_hdr - iSER header
1594814a0a4SEdward Tomasz Napierala  *
1604814a0a4SEdward Tomasz Napierala  * @flags:        flags support (zbva, remote_inv)
1614814a0a4SEdward Tomasz Napierala  * @rsvd:         reserved
1624814a0a4SEdward Tomasz Napierala  * @write_stag:   write rkey
1634814a0a4SEdward Tomasz Napierala  * @write_va:     write virtual address
1644814a0a4SEdward Tomasz Napierala  * @reaf_stag:    read rkey
1654814a0a4SEdward Tomasz Napierala  * @read_va:      read virtual address
1664814a0a4SEdward Tomasz Napierala  */
1674814a0a4SEdward Tomasz Napierala struct iser_hdr {
1684814a0a4SEdward Tomasz Napierala 	u8      flags;
1694814a0a4SEdward Tomasz Napierala 	u8      rsvd[3];
1704814a0a4SEdward Tomasz Napierala 	__be32  write_stag;
1714814a0a4SEdward Tomasz Napierala 	__be64  write_va;
1724814a0a4SEdward Tomasz Napierala 	__be32  read_stag;
1734814a0a4SEdward Tomasz Napierala 	__be64  read_va;
1744814a0a4SEdward Tomasz Napierala } __attribute__((packed));
1754814a0a4SEdward Tomasz Napierala 
1764814a0a4SEdward Tomasz Napierala struct iser_cm_hdr {
1774814a0a4SEdward Tomasz Napierala 	u8      flags;
1784814a0a4SEdward Tomasz Napierala 	u8      rsvd[3];
1794814a0a4SEdward Tomasz Napierala } __packed;
1804814a0a4SEdward Tomasz Napierala 
1814814a0a4SEdward Tomasz Napierala /* Constant PDU lengths calculations */
1824814a0a4SEdward Tomasz Napierala #define ISER_HEADERS_LEN  (sizeof(struct iser_hdr) + ISCSI_BHS_SIZE)
1834814a0a4SEdward Tomasz Napierala 
1844814a0a4SEdward Tomasz Napierala #define ISER_RECV_DATA_SEG_LEN	128
1854814a0a4SEdward Tomasz Napierala #define ISER_RX_PAYLOAD_SIZE	(ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
1864814a0a4SEdward Tomasz Napierala 
1874814a0a4SEdward Tomasz Napierala #define ISER_RX_LOGIN_SIZE	(ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
1884814a0a4SEdward Tomasz Napierala 
1894814a0a4SEdward Tomasz Napierala enum iser_conn_state {
1904814a0a4SEdward Tomasz Napierala 	ISER_CONN_INIT,		   /* descriptor allocd, no conn          */
1914814a0a4SEdward Tomasz Napierala 	ISER_CONN_PENDING,	   /* in the process of being established */
1924814a0a4SEdward Tomasz Napierala 	ISER_CONN_UP,		   /* up and running                      */
1934814a0a4SEdward Tomasz Napierala 	ISER_CONN_TERMINATING,	   /* in the process of being terminated  */
1944814a0a4SEdward Tomasz Napierala 	ISER_CONN_DOWN,		   /* shut down                           */
1954814a0a4SEdward Tomasz Napierala 	ISER_CONN_STATES_NUM
1964814a0a4SEdward Tomasz Napierala };
1974814a0a4SEdward Tomasz Napierala 
1984814a0a4SEdward Tomasz Napierala enum iser_task_status {
1994814a0a4SEdward Tomasz Napierala 	ISER_TASK_STATUS_INIT = 0,
2004814a0a4SEdward Tomasz Napierala 	ISER_TASK_STATUS_STARTED,
2014814a0a4SEdward Tomasz Napierala 	ISER_TASK_STATUS_COMPLETED
2024814a0a4SEdward Tomasz Napierala };
2034814a0a4SEdward Tomasz Napierala 
2044814a0a4SEdward Tomasz Napierala enum iser_data_dir {
2054814a0a4SEdward Tomasz Napierala 	ISER_DIR_IN = 0,	   /* to initiator */
2064814a0a4SEdward Tomasz Napierala 	ISER_DIR_OUT,		   /* from initiator */
2074814a0a4SEdward Tomasz Napierala 	ISER_DIRS_NUM
2084814a0a4SEdward Tomasz Napierala };
2094814a0a4SEdward Tomasz Napierala 
2104814a0a4SEdward Tomasz Napierala /**
2114814a0a4SEdward Tomasz Napierala  * struct iser_mem_reg - iSER memory registration info
2124814a0a4SEdward Tomasz Napierala  *
2134814a0a4SEdward Tomasz Napierala  * @sge:          memory region sg element
2144814a0a4SEdward Tomasz Napierala  * @rkey:         memory region remote key
2154814a0a4SEdward Tomasz Napierala  * @mem_h:        pointer to registration context (FMR/Fastreg)
2164814a0a4SEdward Tomasz Napierala  */
2174814a0a4SEdward Tomasz Napierala struct iser_mem_reg {
2184814a0a4SEdward Tomasz Napierala 	struct ib_sge	 sge;
2194814a0a4SEdward Tomasz Napierala 	u32		 rkey;
2204814a0a4SEdward Tomasz Napierala 	void		*mem_h;
2214814a0a4SEdward Tomasz Napierala };
2224814a0a4SEdward Tomasz Napierala 
2234814a0a4SEdward Tomasz Napierala enum iser_desc_type {
2244814a0a4SEdward Tomasz Napierala 	ISCSI_TX_CONTROL ,
2254814a0a4SEdward Tomasz Napierala 	ISCSI_TX_SCSI_COMMAND,
2264814a0a4SEdward Tomasz Napierala 	ISCSI_TX_DATAOUT
2274814a0a4SEdward Tomasz Napierala };
2284814a0a4SEdward Tomasz Napierala 
2294814a0a4SEdward Tomasz Napierala /**
2304814a0a4SEdward Tomasz Napierala  * struct iser_data_buf - iSER data buffer
2314814a0a4SEdward Tomasz Napierala  *
2324814a0a4SEdward Tomasz Napierala  * @sg:           pointer to the sg list
2334814a0a4SEdward Tomasz Napierala  * @size:         num entries of this sg
2344814a0a4SEdward Tomasz Napierala  * @data_len:     total beffer byte len
2354814a0a4SEdward Tomasz Napierala  * @dma_nents:    returned by dma_map_sg
2364814a0a4SEdward Tomasz Napierala  * @copy_buf:     allocated copy buf for SGs unaligned
2374814a0a4SEdward Tomasz Napierala  *                for rdma which are copied
2384814a0a4SEdward Tomasz Napierala  * @orig_sg:      pointer to the original sg list (in case
2394814a0a4SEdward Tomasz Napierala  *                we used a copy)
2404814a0a4SEdward Tomasz Napierala  * @sg_single:    SG-ified clone of a non SG SC or
2414814a0a4SEdward Tomasz Napierala  *                unaligned SG
2424814a0a4SEdward Tomasz Napierala  */
2434814a0a4SEdward Tomasz Napierala struct iser_data_buf {
2444814a0a4SEdward Tomasz Napierala 	struct scatterlist sgl[ISCSI_ISER_SG_TABLESIZE];
2454814a0a4SEdward Tomasz Napierala 	void               *sg;
246*41dbd9ddSHans Petter Selasky 	int                size;
2474814a0a4SEdward Tomasz Napierala 	unsigned long      data_len;
2484814a0a4SEdward Tomasz Napierala 	unsigned int       dma_nents;
2494814a0a4SEdward Tomasz Napierala 	char               *copy_buf;
2504814a0a4SEdward Tomasz Napierala 	struct scatterlist *orig_sg;
2514814a0a4SEdward Tomasz Napierala 	struct scatterlist sg_single;
2524814a0a4SEdward Tomasz Napierala   };
2534814a0a4SEdward Tomasz Napierala 
2544814a0a4SEdward Tomasz Napierala /* fwd declarations */
2554814a0a4SEdward Tomasz Napierala struct iser_conn;
2564814a0a4SEdward Tomasz Napierala struct ib_conn;
2574814a0a4SEdward Tomasz Napierala struct iser_device;
2584814a0a4SEdward Tomasz Napierala 
2594814a0a4SEdward Tomasz Napierala /**
2604814a0a4SEdward Tomasz Napierala  * struct iser_tx_desc - iSER TX descriptor (for send wr_id)
2614814a0a4SEdward Tomasz Napierala  *
2624814a0a4SEdward Tomasz Napierala  * @iser_header:   iser header
2634814a0a4SEdward Tomasz Napierala  * @iscsi_header:  iscsi header (bhs)
2644814a0a4SEdward Tomasz Napierala  * @type:          command/control/dataout
2654814a0a4SEdward Tomasz Napierala  * @dma_addr:      header buffer dma_address
2664814a0a4SEdward Tomasz Napierala  * @tx_sg:         sg[0] points to iser/iscsi headers
2674814a0a4SEdward Tomasz Napierala  *                 sg[1] optionally points to either of immediate data
2684814a0a4SEdward Tomasz Napierala  *                 unsolicited data-out or control
2694814a0a4SEdward Tomasz Napierala  * @num_sge:       number sges used on this TX task
2704814a0a4SEdward Tomasz Napierala  * @mapped:        indicates if the descriptor is dma mapped
2714814a0a4SEdward Tomasz Napierala  */
2724814a0a4SEdward Tomasz Napierala struct iser_tx_desc {
2734814a0a4SEdward Tomasz Napierala 	struct iser_hdr              iser_header;
2744814a0a4SEdward Tomasz Napierala 	struct iscsi_bhs             iscsi_header __attribute__((packed));
2754814a0a4SEdward Tomasz Napierala 	enum   iser_desc_type        type;
2764814a0a4SEdward Tomasz Napierala 	u64		             dma_addr;
2774814a0a4SEdward Tomasz Napierala 	struct ib_sge		     tx_sg[2];
2784814a0a4SEdward Tomasz Napierala 	int                          num_sge;
2794814a0a4SEdward Tomasz Napierala 	bool                         mapped;
2804814a0a4SEdward Tomasz Napierala };
2814814a0a4SEdward Tomasz Napierala 
2824814a0a4SEdward Tomasz Napierala #define ISER_RX_PAD_SIZE	(256 - (ISER_RX_PAYLOAD_SIZE + \
2834814a0a4SEdward Tomasz Napierala 					sizeof(u64) + sizeof(struct ib_sge)))
2844814a0a4SEdward Tomasz Napierala /**
2854814a0a4SEdward Tomasz Napierala  * struct iser_rx_desc - iSER RX descriptor (for recv wr_id)
2864814a0a4SEdward Tomasz Napierala  *
2874814a0a4SEdward Tomasz Napierala  * @iser_header:   iser header
2884814a0a4SEdward Tomasz Napierala  * @iscsi_header:  iscsi header
2894814a0a4SEdward Tomasz Napierala  * @data:          received data segment
2904814a0a4SEdward Tomasz Napierala  * @dma_addr:      receive buffer dma address
2914814a0a4SEdward Tomasz Napierala  * @rx_sg:         ib_sge of receive buffer
2924814a0a4SEdward Tomasz Napierala  * @pad:           for sense data TODO: Modify to maximum sense length supported
2934814a0a4SEdward Tomasz Napierala  */
2944814a0a4SEdward Tomasz Napierala struct iser_rx_desc {
2954814a0a4SEdward Tomasz Napierala 	struct iser_hdr              iser_header;
2964814a0a4SEdward Tomasz Napierala 	struct iscsi_bhs             iscsi_header;
2974814a0a4SEdward Tomasz Napierala 	char		             data[ISER_RECV_DATA_SEG_LEN];
2984814a0a4SEdward Tomasz Napierala 	u64		             dma_addr;
2994814a0a4SEdward Tomasz Napierala 	struct ib_sge		     rx_sg;
3004814a0a4SEdward Tomasz Napierala 	char		             pad[ISER_RX_PAD_SIZE];
3014814a0a4SEdward Tomasz Napierala } __attribute__((packed));
3024814a0a4SEdward Tomasz Napierala 
3034814a0a4SEdward Tomasz Napierala struct icl_iser_pdu {
3044814a0a4SEdward Tomasz Napierala 	struct icl_pdu               icl_pdu;
3054814a0a4SEdward Tomasz Napierala 	struct iser_tx_desc          desc;
3064814a0a4SEdward Tomasz Napierala 	struct iser_conn             *iser_conn;
3074814a0a4SEdward Tomasz Napierala 	enum iser_task_status        status;
3084814a0a4SEdward Tomasz Napierala 	struct ccb_scsiio 			 *csio;
3094814a0a4SEdward Tomasz Napierala 	int                          command_sent;
3104814a0a4SEdward Tomasz Napierala 	int                          dir[ISER_DIRS_NUM];
3114814a0a4SEdward Tomasz Napierala 	struct iser_mem_reg          rdma_reg[ISER_DIRS_NUM];
3124814a0a4SEdward Tomasz Napierala 	struct iser_data_buf         data[ISER_DIRS_NUM];
3134814a0a4SEdward Tomasz Napierala };
3144814a0a4SEdward Tomasz Napierala 
3154814a0a4SEdward Tomasz Napierala /**
3164814a0a4SEdward Tomasz Napierala  * struct iser_comp - iSER completion context
3174814a0a4SEdward Tomasz Napierala  *
3184814a0a4SEdward Tomasz Napierala  * @device:     pointer to device handle
3194814a0a4SEdward Tomasz Napierala  * @cq:         completion queue
3204814a0a4SEdward Tomasz Napierala  * @wcs:        work completion array
3214814a0a4SEdward Tomasz Napierala  * @tq:    	taskqueue handle
3224814a0a4SEdward Tomasz Napierala  * @task:    	task to run task_fn
3234814a0a4SEdward Tomasz Napierala  * @active_qps: Number of active QPs attached
3244814a0a4SEdward Tomasz Napierala  *              to completion context
3254814a0a4SEdward Tomasz Napierala  */
3264814a0a4SEdward Tomasz Napierala struct iser_comp {
3274814a0a4SEdward Tomasz Napierala 	struct iser_device      *device;
3284814a0a4SEdward Tomasz Napierala 	struct ib_cq		*cq;
3294814a0a4SEdward Tomasz Napierala 	struct ib_wc		 wcs[ISER_WC_BATCH_COUNT];
3304814a0a4SEdward Tomasz Napierala 	struct taskqueue        *tq;
3314814a0a4SEdward Tomasz Napierala 	struct task             task;
3324814a0a4SEdward Tomasz Napierala 	int                      active_qps;
3334814a0a4SEdward Tomasz Napierala };
3344814a0a4SEdward Tomasz Napierala 
3354814a0a4SEdward Tomasz Napierala /**
3364814a0a4SEdward Tomasz Napierala  * struct iser_device - iSER device handle
3374814a0a4SEdward Tomasz Napierala  *
3384814a0a4SEdward Tomasz Napierala  * @ib_device:     RDMA device
3394814a0a4SEdward Tomasz Napierala  * @pd:            Protection Domain for this device
3404814a0a4SEdward Tomasz Napierala  * @dev_attr:      Device attributes container
3414814a0a4SEdward Tomasz Napierala  * @mr:            Global DMA memory region
3424814a0a4SEdward Tomasz Napierala  * @event_handler: IB events handle routine
3434814a0a4SEdward Tomasz Napierala  * @ig_list:	   entry in devices list
3444814a0a4SEdward Tomasz Napierala  * @refcount:      Reference counter, dominated by open iser connections
3454814a0a4SEdward Tomasz Napierala  * @comps_used:    Number of completion contexts used, Min between online
3464814a0a4SEdward Tomasz Napierala  *                 cpus and device max completion vectors
3474814a0a4SEdward Tomasz Napierala  * @comps:         Dinamically allocated array of completion handlers
3484814a0a4SEdward Tomasz Napierala  */
3494814a0a4SEdward Tomasz Napierala struct iser_device {
3504814a0a4SEdward Tomasz Napierala 	struct ib_device             *ib_device;
3514814a0a4SEdward Tomasz Napierala 	struct ib_pd	             *pd;
3524814a0a4SEdward Tomasz Napierala 	struct ib_device_attr	     dev_attr;
3534814a0a4SEdward Tomasz Napierala 	struct ib_mr	             *mr;
3544814a0a4SEdward Tomasz Napierala 	struct ib_event_handler      event_handler;
3554814a0a4SEdward Tomasz Napierala 	struct list_head             ig_list;
3564814a0a4SEdward Tomasz Napierala 	int                          refcount;
3574814a0a4SEdward Tomasz Napierala 	int			     comps_used;
3584814a0a4SEdward Tomasz Napierala 	struct iser_comp	     *comps;
3594814a0a4SEdward Tomasz Napierala };
3604814a0a4SEdward Tomasz Napierala 
3614814a0a4SEdward Tomasz Napierala /**
3624814a0a4SEdward Tomasz Napierala  * struct iser_reg_resources - Fast registration recources
3634814a0a4SEdward Tomasz Napierala  *
3644814a0a4SEdward Tomasz Napierala  * @mr:         memory region
3654814a0a4SEdward Tomasz Napierala  * @mr_valid:   is mr valid indicator
3664814a0a4SEdward Tomasz Napierala  */
3674814a0a4SEdward Tomasz Napierala struct iser_reg_resources {
3684814a0a4SEdward Tomasz Napierala 	struct ib_mr                     *mr;
3694814a0a4SEdward Tomasz Napierala 	u8                                mr_valid:1;
3704814a0a4SEdward Tomasz Napierala };
3714814a0a4SEdward Tomasz Napierala 
3724814a0a4SEdward Tomasz Napierala /**
3734814a0a4SEdward Tomasz Napierala  * struct fast_reg_descriptor - Fast registration descriptor
3744814a0a4SEdward Tomasz Napierala  *
3754814a0a4SEdward Tomasz Napierala  * @list:           entry in connection fastreg pool
3764814a0a4SEdward Tomasz Napierala  * @rsc:            data buffer registration resources
3774814a0a4SEdward Tomasz Napierala  */
3784814a0a4SEdward Tomasz Napierala struct fast_reg_descriptor {
3794814a0a4SEdward Tomasz Napierala 	struct list_head		  list;
3804814a0a4SEdward Tomasz Napierala 	struct iser_reg_resources	  rsc;
3814814a0a4SEdward Tomasz Napierala };
3824814a0a4SEdward Tomasz Napierala 
3834814a0a4SEdward Tomasz Napierala 
3844814a0a4SEdward Tomasz Napierala /**
3854814a0a4SEdward Tomasz Napierala  * struct iser_beacon - beacon to signal all flush errors were drained
3864814a0a4SEdward Tomasz Napierala  *
3874814a0a4SEdward Tomasz Napierala  * @send:           send wr
3884814a0a4SEdward Tomasz Napierala  * @recv:           recv wr
3894814a0a4SEdward Tomasz Napierala  * @flush_lock:     protects flush_cv
3904814a0a4SEdward Tomasz Napierala  * @flush_cv:       condition variable for beacon flush
3914814a0a4SEdward Tomasz Napierala  */
3924814a0a4SEdward Tomasz Napierala struct iser_beacon {
3934814a0a4SEdward Tomasz Napierala 	union {
3944814a0a4SEdward Tomasz Napierala 		struct ib_send_wr	send;
3954814a0a4SEdward Tomasz Napierala 		struct ib_recv_wr	recv;
3964814a0a4SEdward Tomasz Napierala 	};
3974814a0a4SEdward Tomasz Napierala 	struct mtx		     flush_lock;
3984814a0a4SEdward Tomasz Napierala 	struct cv		     flush_cv;
3994814a0a4SEdward Tomasz Napierala };
4004814a0a4SEdward Tomasz Napierala 
4014814a0a4SEdward Tomasz Napierala /**
4024814a0a4SEdward Tomasz Napierala  * struct ib_conn - Infiniband related objects
4034814a0a4SEdward Tomasz Napierala  *
4044814a0a4SEdward Tomasz Napierala  * @cma_id:              rdma_cm connection maneger handle
4054814a0a4SEdward Tomasz Napierala  * @qp:                  Connection Queue-pair
4064814a0a4SEdward Tomasz Napierala  * @device:              reference to iser device
4074814a0a4SEdward Tomasz Napierala  * @comp:                iser completion context
4084814a0a4SEdward Tomasz Napierala   */
4094814a0a4SEdward Tomasz Napierala struct ib_conn {
4104814a0a4SEdward Tomasz Napierala 	struct rdma_cm_id           *cma_id;
4114814a0a4SEdward Tomasz Napierala 	struct ib_qp	            *qp;
4124814a0a4SEdward Tomasz Napierala 	int                          post_recv_buf_count;
4134814a0a4SEdward Tomasz Napierala 	u8                           sig_count;
4144814a0a4SEdward Tomasz Napierala 	struct ib_recv_wr	     rx_wr[ISER_MIN_POSTED_RX];
4154814a0a4SEdward Tomasz Napierala 	struct iser_device          *device;
4164814a0a4SEdward Tomasz Napierala 	struct iser_comp	    *comp;
4174814a0a4SEdward Tomasz Napierala 	struct iser_beacon	     beacon;
4184814a0a4SEdward Tomasz Napierala 	struct mtx               lock;
4194814a0a4SEdward Tomasz Napierala 	union {
4204814a0a4SEdward Tomasz Napierala 		struct {
4214814a0a4SEdward Tomasz Napierala 			struct ib_fmr_pool      *pool;
4224814a0a4SEdward Tomasz Napierala 			struct iser_page_vec	*page_vec;
4234814a0a4SEdward Tomasz Napierala 		} fmr;
4244814a0a4SEdward Tomasz Napierala 		struct {
4254814a0a4SEdward Tomasz Napierala 			struct list_head	 pool;
4264814a0a4SEdward Tomasz Napierala 			int			 pool_size;
4274814a0a4SEdward Tomasz Napierala 		} fastreg;
4284814a0a4SEdward Tomasz Napierala 	};
4294814a0a4SEdward Tomasz Napierala };
4304814a0a4SEdward Tomasz Napierala 
4314814a0a4SEdward Tomasz Napierala struct iser_conn {
4324814a0a4SEdward Tomasz Napierala 	struct icl_conn             icl_conn;
4334814a0a4SEdward Tomasz Napierala 	struct ib_conn               ib_conn;
4344814a0a4SEdward Tomasz Napierala 	struct cv                    up_cv;
4354814a0a4SEdward Tomasz Napierala 	struct list_head             conn_list;
4364814a0a4SEdward Tomasz Napierala 	struct sx		     		 state_mutex;
4374814a0a4SEdward Tomasz Napierala 	enum iser_conn_state	     state;
4384814a0a4SEdward Tomasz Napierala 	int		     				 qp_max_recv_dtos;
4394814a0a4SEdward Tomasz Napierala 	int		     				 min_posted_rx;
4404814a0a4SEdward Tomasz Napierala 	u16                          max_cmds;
4414814a0a4SEdward Tomasz Napierala 	char  			     *login_buf;
4424814a0a4SEdward Tomasz Napierala 	char			     *login_req_buf, *login_resp_buf;
4434814a0a4SEdward Tomasz Napierala 	u64			     login_req_dma, login_resp_dma;
4444814a0a4SEdward Tomasz Napierala 	unsigned int 		     rx_desc_head;
4454814a0a4SEdward Tomasz Napierala 	struct iser_rx_desc	     *rx_descs;
4464814a0a4SEdward Tomasz Napierala 	u32                          num_rx_descs;
44795c4a392SEdward Tomasz Napierala 	bool                         handoff_done;
4484814a0a4SEdward Tomasz Napierala };
4494814a0a4SEdward Tomasz Napierala 
4504814a0a4SEdward Tomasz Napierala /**
4514814a0a4SEdward Tomasz Napierala  * struct iser_global: iSER global context
4524814a0a4SEdward Tomasz Napierala  *
4534814a0a4SEdward Tomasz Napierala  * @device_list_mutex:    protects device_list
4544814a0a4SEdward Tomasz Napierala  * @device_list:          iser devices global list
4554814a0a4SEdward Tomasz Napierala  * @connlist_mutex:       protects connlist
4564814a0a4SEdward Tomasz Napierala  * @connlist:             iser connections global list
4574814a0a4SEdward Tomasz Napierala  * @desc_cache:           kmem cache for tx dataout
4584814a0a4SEdward Tomasz Napierala  * @close_conns_mutex:    serializes conns closure
4594814a0a4SEdward Tomasz Napierala  */
4604814a0a4SEdward Tomasz Napierala struct iser_global {
4614814a0a4SEdward Tomasz Napierala 	struct sx        device_list_mutex;
4624814a0a4SEdward Tomasz Napierala 	struct list_head  device_list;
4634814a0a4SEdward Tomasz Napierala 	struct mtx        connlist_mutex;
4644814a0a4SEdward Tomasz Napierala 	struct list_head  connlist;
4654814a0a4SEdward Tomasz Napierala 	struct sx         close_conns_mutex;
4664814a0a4SEdward Tomasz Napierala };
4674814a0a4SEdward Tomasz Napierala 
4684814a0a4SEdward Tomasz Napierala extern struct iser_global ig;
4694814a0a4SEdward Tomasz Napierala extern int iser_debug;
4704814a0a4SEdward Tomasz Napierala 
4714814a0a4SEdward Tomasz Napierala void
4724814a0a4SEdward Tomasz Napierala iser_create_send_desc(struct iser_conn *, struct iser_tx_desc *);
4734814a0a4SEdward Tomasz Napierala 
4744814a0a4SEdward Tomasz Napierala int
4754814a0a4SEdward Tomasz Napierala iser_post_recvl(struct iser_conn *);
4764814a0a4SEdward Tomasz Napierala 
4774814a0a4SEdward Tomasz Napierala int
4784814a0a4SEdward Tomasz Napierala iser_post_recvm(struct iser_conn *, int);
4794814a0a4SEdward Tomasz Napierala 
4804814a0a4SEdward Tomasz Napierala int
4814814a0a4SEdward Tomasz Napierala iser_alloc_login_buf(struct iser_conn *iser_conn);
4824814a0a4SEdward Tomasz Napierala 
4834814a0a4SEdward Tomasz Napierala void
4844814a0a4SEdward Tomasz Napierala iser_free_login_buf(struct iser_conn *iser_conn);
4854814a0a4SEdward Tomasz Napierala 
4864814a0a4SEdward Tomasz Napierala int
4874814a0a4SEdward Tomasz Napierala iser_post_send(struct ib_conn *, struct iser_tx_desc *, bool);
4884814a0a4SEdward Tomasz Napierala 
4894814a0a4SEdward Tomasz Napierala void
4904814a0a4SEdward Tomasz Napierala iser_snd_completion(struct iser_tx_desc *, struct ib_conn *);
4914814a0a4SEdward Tomasz Napierala 
4924814a0a4SEdward Tomasz Napierala void
4934814a0a4SEdward Tomasz Napierala iser_rcv_completion(struct iser_rx_desc *, unsigned long,
4944814a0a4SEdward Tomasz Napierala 		    struct ib_conn *);
4954814a0a4SEdward Tomasz Napierala 
4964814a0a4SEdward Tomasz Napierala void
4974814a0a4SEdward Tomasz Napierala iser_pdu_free(struct icl_conn *, struct icl_pdu *);
4984814a0a4SEdward Tomasz Napierala 
4994814a0a4SEdward Tomasz Napierala struct icl_pdu *
5004814a0a4SEdward Tomasz Napierala iser_new_pdu(struct icl_conn *ic, int flags);
5014814a0a4SEdward Tomasz Napierala 
5024814a0a4SEdward Tomasz Napierala int
5034814a0a4SEdward Tomasz Napierala iser_alloc_rx_descriptors(struct iser_conn *, int);
5044814a0a4SEdward Tomasz Napierala 
5054814a0a4SEdward Tomasz Napierala void
5064814a0a4SEdward Tomasz Napierala iser_free_rx_descriptors(struct iser_conn *);
5074814a0a4SEdward Tomasz Napierala 
5084814a0a4SEdward Tomasz Napierala int
5094814a0a4SEdward Tomasz Napierala iser_initialize_headers(struct icl_iser_pdu *, struct iser_conn *);
5104814a0a4SEdward Tomasz Napierala 
5114814a0a4SEdward Tomasz Napierala int
5124814a0a4SEdward Tomasz Napierala iser_send_control(struct iser_conn *, struct icl_iser_pdu *);
5134814a0a4SEdward Tomasz Napierala 
5144814a0a4SEdward Tomasz Napierala int
5154814a0a4SEdward Tomasz Napierala iser_send_command(struct iser_conn *, struct icl_iser_pdu *);
5164814a0a4SEdward Tomasz Napierala 
5174814a0a4SEdward Tomasz Napierala int
5184814a0a4SEdward Tomasz Napierala iser_reg_rdma_mem(struct icl_iser_pdu *, enum iser_data_dir);
5194814a0a4SEdward Tomasz Napierala 
5204814a0a4SEdward Tomasz Napierala void
5214814a0a4SEdward Tomasz Napierala iser_unreg_rdma_mem(struct icl_iser_pdu *, enum iser_data_dir);
5224814a0a4SEdward Tomasz Napierala 
5234814a0a4SEdward Tomasz Napierala int
5244814a0a4SEdward Tomasz Napierala iser_create_fastreg_pool(struct ib_conn *, unsigned);
5254814a0a4SEdward Tomasz Napierala 
5264814a0a4SEdward Tomasz Napierala void
5274814a0a4SEdward Tomasz Napierala iser_free_fastreg_pool(struct ib_conn *);
5284814a0a4SEdward Tomasz Napierala 
5294814a0a4SEdward Tomasz Napierala int
5304814a0a4SEdward Tomasz Napierala iser_dma_map_task_data(struct icl_iser_pdu *,
5314814a0a4SEdward Tomasz Napierala 		       struct iser_data_buf *, enum iser_data_dir,
5324814a0a4SEdward Tomasz Napierala 		       enum dma_data_direction);
5334814a0a4SEdward Tomasz Napierala 
5344814a0a4SEdward Tomasz Napierala int
5354814a0a4SEdward Tomasz Napierala iser_conn_terminate(struct iser_conn *);
5364814a0a4SEdward Tomasz Napierala 
5374814a0a4SEdward Tomasz Napierala void
5384814a0a4SEdward Tomasz Napierala iser_free_ib_conn_res(struct iser_conn *, bool);
5394814a0a4SEdward Tomasz Napierala 
5404814a0a4SEdward Tomasz Napierala void
5414814a0a4SEdward Tomasz Napierala iser_dma_unmap_task_data(struct icl_iser_pdu *, struct iser_data_buf *,
5424814a0a4SEdward Tomasz Napierala 			 enum dma_data_direction);
5434814a0a4SEdward Tomasz Napierala 
5444814a0a4SEdward Tomasz Napierala int
5454814a0a4SEdward Tomasz Napierala iser_cma_handler(struct rdma_cm_id *, struct rdma_cm_event *);
5464814a0a4SEdward Tomasz Napierala 
5474814a0a4SEdward Tomasz Napierala #endif /* !ICL_ISER_H */
548