162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * iSCSI over TCP/IP Data-Path lib 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2008 Mike Christie 662306a36Sopenharmony_ci * Copyright (C) 2008 Red Hat, Inc. All rights reserved. 762306a36Sopenharmony_ci * maintained by open-iscsi@googlegroups.com 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef LIBISCSI_TCP_H 1162306a36Sopenharmony_ci#define LIBISCSI_TCP_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <scsi/libiscsi.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct iscsi_tcp_conn; 1662306a36Sopenharmony_cistruct iscsi_segment; 1762306a36Sopenharmony_cistruct sk_buff; 1862306a36Sopenharmony_cistruct ahash_request; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_citypedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, 2162306a36Sopenharmony_ci struct iscsi_segment *); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct iscsi_segment { 2462306a36Sopenharmony_ci unsigned char *data; 2562306a36Sopenharmony_ci unsigned int size; 2662306a36Sopenharmony_ci unsigned int copied; 2762306a36Sopenharmony_ci unsigned int total_size; 2862306a36Sopenharmony_ci unsigned int total_copied; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci struct ahash_request *hash; 3162306a36Sopenharmony_ci unsigned char padbuf[ISCSI_PAD_LEN]; 3262306a36Sopenharmony_ci unsigned char recv_digest[ISCSI_DIGEST_SIZE]; 3362306a36Sopenharmony_ci unsigned char digest[ISCSI_DIGEST_SIZE]; 3462306a36Sopenharmony_ci unsigned int digest_len; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci struct scatterlist *sg; 3762306a36Sopenharmony_ci void *sg_mapped; 3862306a36Sopenharmony_ci unsigned int sg_offset; 3962306a36Sopenharmony_ci bool atomic_mapped; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci iscsi_segment_done_fn_t *done; 4262306a36Sopenharmony_ci}; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Socket connection receive helper */ 4562306a36Sopenharmony_cistruct iscsi_tcp_recv { 4662306a36Sopenharmony_ci struct iscsi_hdr *hdr; 4762306a36Sopenharmony_ci struct iscsi_segment segment; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci /* Allocate buffer for BHS + AHS */ 5062306a36Sopenharmony_ci uint32_t hdr_buf[64]; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* copied and flipped values */ 5362306a36Sopenharmony_ci int datalen; 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistruct iscsi_tcp_conn { 5762306a36Sopenharmony_ci struct iscsi_conn *iscsi_conn; 5862306a36Sopenharmony_ci void *dd_data; 5962306a36Sopenharmony_ci int stop_stage; /* conn_stop() flag: * 6062306a36Sopenharmony_ci * stop to recover, * 6162306a36Sopenharmony_ci * stop to terminate */ 6262306a36Sopenharmony_ci /* control data */ 6362306a36Sopenharmony_ci struct iscsi_tcp_recv in; /* TCP receive context */ 6462306a36Sopenharmony_ci /* CRC32C (Rx) LLD should set this is they do not offload */ 6562306a36Sopenharmony_ci struct ahash_request *rx_hash; 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cistruct iscsi_tcp_task { 6962306a36Sopenharmony_ci uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ 7062306a36Sopenharmony_ci int data_offset; 7162306a36Sopenharmony_ci struct iscsi_r2t_info *r2t; /* in progress solict R2T */ 7262306a36Sopenharmony_ci struct iscsi_pool r2tpool; 7362306a36Sopenharmony_ci struct kfifo r2tqueue; 7462306a36Sopenharmony_ci void *dd_data; 7562306a36Sopenharmony_ci spinlock_t pool2queue; 7662306a36Sopenharmony_ci spinlock_t queue2pool; 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cienum { 8062306a36Sopenharmony_ci ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ 8162306a36Sopenharmony_ci ISCSI_TCP_SKB_DONE, /* skb is out of data */ 8262306a36Sopenharmony_ci ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ 8362306a36Sopenharmony_ci ISCSI_TCP_SUSPENDED, /* conn is suspended */ 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciextern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); 8762306a36Sopenharmony_ciextern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, 8862306a36Sopenharmony_ci unsigned int offset, bool offloaded, int *status); 8962306a36Sopenharmony_ciextern void iscsi_tcp_cleanup_task(struct iscsi_task *task); 9062306a36Sopenharmony_ciextern int iscsi_tcp_task_init(struct iscsi_task *task); 9162306a36Sopenharmony_ciextern int iscsi_tcp_task_xmit(struct iscsi_task *task); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci/* segment helpers */ 9462306a36Sopenharmony_ciextern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); 9562306a36Sopenharmony_ciextern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, 9662306a36Sopenharmony_ci struct iscsi_segment *segment, int recv, 9762306a36Sopenharmony_ci unsigned copied); 9862306a36Sopenharmony_ciextern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciextern void iscsi_segment_init_linear(struct iscsi_segment *segment, 10162306a36Sopenharmony_ci void *data, size_t size, 10262306a36Sopenharmony_ci iscsi_segment_done_fn_t *done, 10362306a36Sopenharmony_ci struct ahash_request *hash); 10462306a36Sopenharmony_ciextern int 10562306a36Sopenharmony_ciiscsi_segment_seek_sg(struct iscsi_segment *segment, 10662306a36Sopenharmony_ci struct scatterlist *sg_list, unsigned int sg_count, 10762306a36Sopenharmony_ci unsigned int offset, size_t size, 10862306a36Sopenharmony_ci iscsi_segment_done_fn_t *done, 10962306a36Sopenharmony_ci struct ahash_request *hash); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* digest helpers */ 11262306a36Sopenharmony_ciextern void iscsi_tcp_dgst_header(struct ahash_request *hash, const void *hdr, 11362306a36Sopenharmony_ci size_t hdrlen, 11462306a36Sopenharmony_ci unsigned char digest[ISCSI_DIGEST_SIZE]); 11562306a36Sopenharmony_ciextern struct iscsi_cls_conn * 11662306a36Sopenharmony_ciiscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, 11762306a36Sopenharmony_ci uint32_t conn_idx); 11862306a36Sopenharmony_ciextern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* misc helpers */ 12162306a36Sopenharmony_ciextern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); 12262306a36Sopenharmony_ciextern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); 12362306a36Sopenharmony_ciextern int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf); 12462306a36Sopenharmony_ciextern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, 12562306a36Sopenharmony_ci struct iscsi_stats *stats); 12662306a36Sopenharmony_ci#endif /* LIBISCSI_TCP_H */ 127