1255570Strasz/*-
2255570Strasz * Copyright (c) 2012 The FreeBSD Foundation
3255570Strasz * All rights reserved.
4255570Strasz *
5255570Strasz * This software was developed by Edward Tomasz Napierala under sponsorship
6255570Strasz * from the FreeBSD Foundation.
7255570Strasz *
8255570Strasz * Redistribution and use in source and binary forms, with or without
9255570Strasz * modification, are permitted provided that the following conditions
10255570Strasz * are met:
11255570Strasz * 1. Redistributions of source code must retain the above copyright
12255570Strasz *    notice, this list of conditions and the following disclaimer.
13255570Strasz * 2. Redistributions in binary form must reproduce the above copyright
14255570Strasz *    notice, this list of conditions and the following disclaimer in the
15255570Strasz *    documentation and/or other materials provided with the distribution.
16255570Strasz *
17255570Strasz * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18255570Strasz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19255570Strasz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20255570Strasz * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21255570Strasz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22255570Strasz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23255570Strasz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24255570Strasz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25255570Strasz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26255570Strasz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27255570Strasz * SUCH DAMAGE.
28255570Strasz *
29255570Strasz * $FreeBSD$
30255570Strasz */
31255570Strasz
32255570Strasz#ifndef ICL_H
33255570Strasz#define	ICL_H
34255570Strasz
35255570Strasz/*
36255570Strasz * iSCSI Common Layer.  It's used by both the initiator and target to send
37255570Strasz * and receive iSCSI PDUs.
38255570Strasz */
39255570Strasz
40277963Strasz#include <sys/types.h>
41277963Strasz#include <sys/kobj.h>
42277963Strasz#include <sys/condvar.h>
43277963Strasz#include <sys/sysctl.h>
44277963Strasz
45277963StraszSYSCTL_DECL(_kern_icl);
46277963Strasz
47277963Straszextern int icl_debug;
48277963Strasz
49277963Strasz#define	ICL_DEBUG(X, ...)						\
50277963Strasz	do {								\
51277963Strasz		if (icl_debug > 1)					\
52277963Strasz			printf("%s: " X "\n", __func__, ## __VA_ARGS__);\
53277963Strasz	} while (0)
54277963Strasz
55277963Strasz#define	ICL_WARN(X, ...)						\
56277963Strasz	do {								\
57277963Strasz		if (icl_debug > 0) {					\
58277963Strasz			printf("WARNING: %s: " X "\n",			\
59277963Strasz			    __func__, ## __VA_ARGS__);			\
60277963Strasz		}							\
61277963Strasz	} while (0)
62277963Strasz
63255570Straszstruct icl_conn;
64277963Straszstruct ccb_scsiio;
65277963Straszunion ctl_io;
66255570Strasz
67255570Straszstruct icl_pdu {
68264109Strasz	STAILQ_ENTRY(icl_pdu)	ip_next;
69255570Strasz	struct icl_conn		*ip_conn;
70255570Strasz	struct iscsi_bhs	*ip_bhs;
71255570Strasz	struct mbuf		*ip_bhs_mbuf;
72255570Strasz	size_t			ip_ahs_len;
73255570Strasz	struct mbuf		*ip_ahs_mbuf;
74255570Strasz	size_t			ip_data_len;
75255570Strasz	struct mbuf		*ip_data_mbuf;
76255570Strasz
77255570Strasz	/*
78255570Strasz	 * User (initiator or provider) private fields.
79255570Strasz	 */
80255570Strasz	uint32_t		ip_prv0;
81255570Strasz	uint32_t		ip_prv1;
82255570Strasz	uint32_t		ip_prv2;
83255570Strasz};
84255570Strasz
85255570Strasz#define ICL_CONN_STATE_INVALID		0
86255570Strasz#define ICL_CONN_STATE_BHS		1
87255570Strasz#define ICL_CONN_STATE_AHS		2
88255570Strasz#define ICL_CONN_STATE_HEADER_DIGEST	3
89255570Strasz#define ICL_CONN_STATE_DATA		4
90255570Strasz#define ICL_CONN_STATE_DATA_DIGEST	5
91255570Strasz
92255570Strasz#define	ICL_MAX_DATA_SEGMENT_LENGTH	(128 * 1024)
93255570Strasz
94255570Straszstruct icl_conn {
95277963Strasz	KOBJ_FIELDS;
96264022Strasz	struct mtx		*ic_lock;
97255570Strasz	struct socket		*ic_socket;
98263743Strasz#ifdef DIAGNOSTIC
99255570Strasz	volatile u_int		ic_outstanding_pdus;
100263743Strasz#endif
101264109Strasz	STAILQ_HEAD(, icl_pdu)	ic_to_send;
102264122Strasz	bool			ic_check_send_space;
103255570Strasz	size_t			ic_receive_len;
104255570Strasz	int			ic_receive_state;
105255570Strasz	struct icl_pdu		*ic_receive_pdu;
106255570Strasz	struct cv		ic_send_cv;
107255570Strasz	struct cv		ic_receive_cv;
108255570Strasz	bool			ic_header_crc32c;
109255570Strasz	bool			ic_data_crc32c;
110255570Strasz	bool			ic_send_running;
111255570Strasz	bool			ic_receive_running;
112255570Strasz	size_t			ic_max_data_segment_length;
113300368Strasz	size_t			ic_maxtags;
114255570Strasz	bool			ic_disconnecting;
115255570Strasz	bool			ic_iser;
116300369Strasz	bool			ic_unmapped;
117264023Strasz	const char		*ic_name;
118278232Strasz	const char		*ic_offload;
119255570Strasz
120255570Strasz	void			(*ic_receive)(struct icl_pdu *);
121255570Strasz	void			(*ic_error)(struct icl_conn *);
122255570Strasz
123255570Strasz	/*
124255570Strasz	 * User (initiator or provider) private fields.
125255570Strasz	 */
126255570Strasz	void			*ic_prv0;
127255570Strasz};
128255570Strasz
129300592Straszstruct icl_conn	*icl_new_conn(const char *offload, bool iser, const char *name,
130277963Strasz		    struct mtx *lock);
131300592Straszint		icl_limits(const char *offload, bool iser, size_t *limitp);
132255570Strasz
133300592Straszint		icl_register(const char *offload, bool iser, int priority,
134277963Strasz		    int (*limits)(size_t *),
135277963Strasz		    struct icl_conn *(*new_conn)(const char *, struct mtx *));
136300592Straszint		icl_unregister(const char *offload, bool rdma);
137277963Strasz
138255570Strasz#ifdef ICL_KERNEL_PROXY
139255570Strasz
140255570Straszstruct sockaddr;
141255570Straszstruct icl_listen;
142255570Strasz
143255570Strasz/*
144255570Strasz * Target part.
145255570Strasz */
146264530Straszstruct icl_listen	*icl_listen_new(void (*accept_cb)(struct socket *,
147264530Strasz			    struct sockaddr *, int));
148255570Straszvoid			icl_listen_free(struct icl_listen *il);
149264526Straszint			icl_listen_add(struct icl_listen *il, bool rdma,
150264526Strasz			    int domain, int socktype, int protocol,
151264526Strasz			    struct sockaddr *sa, int portal_id);
152255570Straszint			icl_listen_remove(struct icl_listen *il, struct sockaddr *sa);
153255570Strasz
154255570Strasz/*
155300061Strasz * Those two are not a public API; only to be used between icl_soft.c
156300061Strasz * and icl_soft_proxy.c.
157255570Strasz */
158300044Straszint			icl_soft_handoff_sock(struct icl_conn *ic, struct socket *so);
159300044Straszint			icl_soft_proxy_connect(struct icl_conn *ic, int domain,
160300044Strasz			    int socktype, int protocol, struct sockaddr *from_sa,
161300044Strasz			    struct sockaddr *to_sa);
162255570Strasz#endif /* ICL_KERNEL_PROXY */
163255570Strasz#endif /* !ICL_H */
164