18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * iSCSI over TCP/IP Data-Path lib 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2008 Mike Christie 68c2ecf20Sopenharmony_ci * Copyright (C) 2008 Red Hat, Inc. All rights reserved. 78c2ecf20Sopenharmony_ci * maintained by open-iscsi@googlegroups.com 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef LIBISCSI_TCP_H 118c2ecf20Sopenharmony_ci#define LIBISCSI_TCP_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <scsi/libiscsi.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistruct iscsi_tcp_conn; 168c2ecf20Sopenharmony_cistruct iscsi_segment; 178c2ecf20Sopenharmony_cistruct sk_buff; 188c2ecf20Sopenharmony_cistruct ahash_request; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_citypedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, 218c2ecf20Sopenharmony_ci struct iscsi_segment *); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct iscsi_segment { 248c2ecf20Sopenharmony_ci unsigned char *data; 258c2ecf20Sopenharmony_ci unsigned int size; 268c2ecf20Sopenharmony_ci unsigned int copied; 278c2ecf20Sopenharmony_ci unsigned int total_size; 288c2ecf20Sopenharmony_ci unsigned int total_copied; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci struct ahash_request *hash; 318c2ecf20Sopenharmony_ci unsigned char padbuf[ISCSI_PAD_LEN]; 328c2ecf20Sopenharmony_ci unsigned char recv_digest[ISCSI_DIGEST_SIZE]; 338c2ecf20Sopenharmony_ci unsigned char digest[ISCSI_DIGEST_SIZE]; 348c2ecf20Sopenharmony_ci unsigned int digest_len; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci struct scatterlist *sg; 378c2ecf20Sopenharmony_ci void *sg_mapped; 388c2ecf20Sopenharmony_ci unsigned int sg_offset; 398c2ecf20Sopenharmony_ci bool atomic_mapped; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci iscsi_segment_done_fn_t *done; 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* Socket connection receive helper */ 458c2ecf20Sopenharmony_cistruct iscsi_tcp_recv { 468c2ecf20Sopenharmony_ci struct iscsi_hdr *hdr; 478c2ecf20Sopenharmony_ci struct iscsi_segment segment; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci /* Allocate buffer for BHS + AHS */ 508c2ecf20Sopenharmony_ci uint32_t hdr_buf[64]; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci /* copied and flipped values */ 538c2ecf20Sopenharmony_ci int datalen; 548c2ecf20Sopenharmony_ci}; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistruct iscsi_tcp_conn { 578c2ecf20Sopenharmony_ci struct iscsi_conn *iscsi_conn; 588c2ecf20Sopenharmony_ci void *dd_data; 598c2ecf20Sopenharmony_ci int stop_stage; /* conn_stop() flag: * 608c2ecf20Sopenharmony_ci * stop to recover, * 618c2ecf20Sopenharmony_ci * stop to terminate */ 628c2ecf20Sopenharmony_ci /* control data */ 638c2ecf20Sopenharmony_ci struct iscsi_tcp_recv in; /* TCP receive context */ 648c2ecf20Sopenharmony_ci /* CRC32C (Rx) LLD should set this is they do not offload */ 658c2ecf20Sopenharmony_ci struct ahash_request *rx_hash; 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistruct iscsi_tcp_task { 698c2ecf20Sopenharmony_ci uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ 708c2ecf20Sopenharmony_ci int data_offset; 718c2ecf20Sopenharmony_ci struct iscsi_r2t_info *r2t; /* in progress solict R2T */ 728c2ecf20Sopenharmony_ci struct iscsi_pool r2tpool; 738c2ecf20Sopenharmony_ci struct kfifo r2tqueue; 748c2ecf20Sopenharmony_ci void *dd_data; 758c2ecf20Sopenharmony_ci spinlock_t pool2queue; 768c2ecf20Sopenharmony_ci spinlock_t queue2pool; 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cienum { 808c2ecf20Sopenharmony_ci ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ 818c2ecf20Sopenharmony_ci ISCSI_TCP_SKB_DONE, /* skb is out of data */ 828c2ecf20Sopenharmony_ci ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ 838c2ecf20Sopenharmony_ci ISCSI_TCP_SUSPENDED, /* conn is suspended */ 848c2ecf20Sopenharmony_ci}; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciextern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); 878c2ecf20Sopenharmony_ciextern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, 888c2ecf20Sopenharmony_ci unsigned int offset, bool offloaded, int *status); 898c2ecf20Sopenharmony_ciextern void iscsi_tcp_cleanup_task(struct iscsi_task *task); 908c2ecf20Sopenharmony_ciextern int iscsi_tcp_task_init(struct iscsi_task *task); 918c2ecf20Sopenharmony_ciextern int iscsi_tcp_task_xmit(struct iscsi_task *task); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci/* segment helpers */ 948c2ecf20Sopenharmony_ciextern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); 958c2ecf20Sopenharmony_ciextern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, 968c2ecf20Sopenharmony_ci struct iscsi_segment *segment, int recv, 978c2ecf20Sopenharmony_ci unsigned copied); 988c2ecf20Sopenharmony_ciextern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ciextern void iscsi_segment_init_linear(struct iscsi_segment *segment, 1018c2ecf20Sopenharmony_ci void *data, size_t size, 1028c2ecf20Sopenharmony_ci iscsi_segment_done_fn_t *done, 1038c2ecf20Sopenharmony_ci struct ahash_request *hash); 1048c2ecf20Sopenharmony_ciextern int 1058c2ecf20Sopenharmony_ciiscsi_segment_seek_sg(struct iscsi_segment *segment, 1068c2ecf20Sopenharmony_ci struct scatterlist *sg_list, unsigned int sg_count, 1078c2ecf20Sopenharmony_ci unsigned int offset, size_t size, 1088c2ecf20Sopenharmony_ci iscsi_segment_done_fn_t *done, 1098c2ecf20Sopenharmony_ci struct ahash_request *hash); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* digest helpers */ 1128c2ecf20Sopenharmony_ciextern void iscsi_tcp_dgst_header(struct ahash_request *hash, const void *hdr, 1138c2ecf20Sopenharmony_ci size_t hdrlen, 1148c2ecf20Sopenharmony_ci unsigned char digest[ISCSI_DIGEST_SIZE]); 1158c2ecf20Sopenharmony_ciextern struct iscsi_cls_conn * 1168c2ecf20Sopenharmony_ciiscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, 1178c2ecf20Sopenharmony_ci uint32_t conn_idx); 1188c2ecf20Sopenharmony_ciextern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* misc helpers */ 1218c2ecf20Sopenharmony_ciextern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); 1228c2ecf20Sopenharmony_ciextern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); 1238c2ecf20Sopenharmony_ciextern int iscsi_tcp_set_max_r2t(struct iscsi_conn *conn, char *buf); 1248c2ecf20Sopenharmony_ciextern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, 1258c2ecf20Sopenharmony_ci struct iscsi_stats *stats); 1268c2ecf20Sopenharmony_ci#endif /* LIBISCSI_TCP_H */ 127