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