xref: /openbmc/linux/include/scsi/libiscsi_tcp.h (revision 70c7c88a)
1a081c13eSMike Christie /*
2a081c13eSMike Christie  * iSCSI over TCP/IP Data-Path lib
3a081c13eSMike Christie  *
4a081c13eSMike Christie  * Copyright (C) 2008 Mike Christie
5a081c13eSMike Christie  * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
6a081c13eSMike Christie  * maintained by open-iscsi@googlegroups.com
7a081c13eSMike Christie  *
8a081c13eSMike Christie  * This program is free software; you can redistribute it and/or modify
9a081c13eSMike Christie  * it under the terms of the GNU General Public License as published
10a081c13eSMike Christie  * by the Free Software Foundation; either version 2 of the License, or
11a081c13eSMike Christie  * (at your option) any later version.
12a081c13eSMike Christie  *
13a081c13eSMike Christie  * This program is distributed in the hope that it will be useful, but
14a081c13eSMike Christie  * WITHOUT ANY WARRANTY; without even the implied warranty of
15a081c13eSMike Christie  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16a081c13eSMike Christie  * General Public License for more details.
17a081c13eSMike Christie  *
18a081c13eSMike Christie  * See the file COPYING included with this distribution for more details.
19a081c13eSMike Christie  */
20a081c13eSMike Christie 
21a081c13eSMike Christie #ifndef LIBISCSI_TCP_H
22a081c13eSMike Christie #define LIBISCSI_TCP_H
23a081c13eSMike Christie 
24a081c13eSMike Christie #include <scsi/libiscsi.h>
25a081c13eSMike Christie 
26a081c13eSMike Christie struct iscsi_tcp_conn;
27a081c13eSMike Christie struct iscsi_segment;
28a081c13eSMike Christie struct sk_buff;
29a081c13eSMike Christie struct hash_desc;
30a081c13eSMike Christie 
31a081c13eSMike Christie typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *,
32a081c13eSMike Christie 				    struct iscsi_segment *);
33a081c13eSMike Christie 
34a081c13eSMike Christie struct iscsi_segment {
35a081c13eSMike Christie 	unsigned char		*data;
36a081c13eSMike Christie 	unsigned int		size;
37a081c13eSMike Christie 	unsigned int		copied;
38a081c13eSMike Christie 	unsigned int		total_size;
39a081c13eSMike Christie 	unsigned int		total_copied;
40a081c13eSMike Christie 
41a081c13eSMike Christie 	struct hash_desc	*hash;
422856830bSKaren Xie 	unsigned char		padbuf[ISCSI_PAD_LEN];
43a081c13eSMike Christie 	unsigned char		recv_digest[ISCSI_DIGEST_SIZE];
44a081c13eSMike Christie 	unsigned char		digest[ISCSI_DIGEST_SIZE];
45a081c13eSMike Christie 	unsigned int		digest_len;
46a081c13eSMike Christie 
47a081c13eSMike Christie 	struct scatterlist	*sg;
48a081c13eSMike Christie 	void			*sg_mapped;
49a081c13eSMike Christie 	unsigned int		sg_offset;
5070c7c88aSMike Christie 	bool			atomic_mapped;
51a081c13eSMike Christie 
52a081c13eSMike Christie 	iscsi_segment_done_fn_t	*done;
53a081c13eSMike Christie };
54a081c13eSMike Christie 
55a081c13eSMike Christie /* Socket connection recieve helper */
56a081c13eSMike Christie struct iscsi_tcp_recv {
57a081c13eSMike Christie 	struct iscsi_hdr	*hdr;
58a081c13eSMike Christie 	struct iscsi_segment	segment;
59a081c13eSMike Christie 
60a081c13eSMike Christie 	/* Allocate buffer for BHS + AHS */
61a081c13eSMike Christie 	uint32_t		hdr_buf[64];
62a081c13eSMike Christie 
63a081c13eSMike Christie 	/* copied and flipped values */
64a081c13eSMike Christie 	int			datalen;
65a081c13eSMike Christie };
66a081c13eSMike Christie 
67a081c13eSMike Christie struct iscsi_tcp_conn {
68a081c13eSMike Christie 	struct iscsi_conn	*iscsi_conn;
69a081c13eSMike Christie 	void			*dd_data;
70a081c13eSMike Christie 	int			stop_stage;	/* conn_stop() flag: *
71a081c13eSMike Christie 						 * stop to recover,  *
72a081c13eSMike Christie 						 * stop to terminate */
73a081c13eSMike Christie 	/* control data */
74a081c13eSMike Christie 	struct iscsi_tcp_recv	in;		/* TCP receive context */
75a081c13eSMike Christie 	/* CRC32C (Rx) LLD should set this is they do not offload */
76a081c13eSMike Christie 	struct hash_desc	*rx_hash;
77a081c13eSMike Christie };
78a081c13eSMike Christie 
79a081c13eSMike Christie struct iscsi_tcp_task {
80a081c13eSMike Christie 	uint32_t		exp_datasn;	/* expected target's R2TSN/DataSN */
81a081c13eSMike Christie 	int			data_offset;
82a081c13eSMike Christie 	struct iscsi_r2t_info	*r2t;		/* in progress solict R2T */
83a081c13eSMike Christie 	struct iscsi_pool	r2tpool;
8445465487SStefani Seibold 	struct kfifo		r2tqueue;
85a081c13eSMike Christie 	void			*dd_data;
86a081c13eSMike Christie };
87a081c13eSMike Christie 
88a081c13eSMike Christie enum {
89a081c13eSMike Christie 	ISCSI_TCP_SEGMENT_DONE,		/* curr seg has been processed */
90a081c13eSMike Christie 	ISCSI_TCP_SKB_DONE,		/* skb is out of data */
91a081c13eSMike Christie 	ISCSI_TCP_CONN_ERR,		/* iscsi layer has fired a conn err */
92a081c13eSMike Christie 	ISCSI_TCP_SUSPENDED,		/* conn is suspended */
93a081c13eSMike Christie };
94a081c13eSMike Christie 
95a081c13eSMike Christie extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn);
96a081c13eSMike Christie extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb,
97a081c13eSMike Christie 			      unsigned int offset, bool offloaded, int *status);
98a081c13eSMike Christie extern void iscsi_tcp_cleanup_task(struct iscsi_task *task);
99a081c13eSMike Christie extern int iscsi_tcp_task_init(struct iscsi_task *task);
100a081c13eSMike Christie extern int iscsi_tcp_task_xmit(struct iscsi_task *task);
101a081c13eSMike Christie 
102a081c13eSMike Christie /* segment helpers */
103a081c13eSMike Christie extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn);
1046df19a79SMike Christie extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn,
1056df19a79SMike Christie 				  struct iscsi_segment *segment, int recv,
106a081c13eSMike Christie 				  unsigned copied);
107a081c13eSMike Christie extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment);
108a081c13eSMike Christie 
109a081c13eSMike Christie extern void iscsi_segment_init_linear(struct iscsi_segment *segment,
110a081c13eSMike Christie 				      void *data, size_t size,
111a081c13eSMike Christie 				      iscsi_segment_done_fn_t *done,
112a081c13eSMike Christie 				      struct hash_desc *hash);
113a081c13eSMike Christie extern int
114a081c13eSMike Christie iscsi_segment_seek_sg(struct iscsi_segment *segment,
115a081c13eSMike Christie 		      struct scatterlist *sg_list, unsigned int sg_count,
116a081c13eSMike Christie 		      unsigned int offset, size_t size,
117a081c13eSMike Christie 		      iscsi_segment_done_fn_t *done, struct hash_desc *hash);
118a081c13eSMike Christie 
119a081c13eSMike Christie /* digest helpers */
120a081c13eSMike Christie extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr,
121a081c13eSMike Christie 				  size_t hdrlen,
122a081c13eSMike Christie 				  unsigned char digest[ISCSI_DIGEST_SIZE]);
123a081c13eSMike Christie extern struct iscsi_cls_conn *
124a081c13eSMike Christie iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size,
125a081c13eSMike Christie 		     uint32_t conn_idx);
126a081c13eSMike Christie extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn);
127a081c13eSMike Christie 
128a081c13eSMike Christie /* misc helpers */
129a081c13eSMike Christie extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session);
130a081c13eSMike Christie extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session);
131a081c13eSMike Christie 
132a081c13eSMike Christie extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn,
133a081c13eSMike Christie 				     struct iscsi_stats *stats);
134a081c13eSMike Christie #endif /* LIBISCSI_TCP_H */
135