18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/* QLogic iSCSI Offload Driver
38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Cavium Inc.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/types.h>
78c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
88c2ecf20Sopenharmony_ci#include "qedi_hsi.h"
98c2ecf20Sopenharmony_ci#include <linux/qed/qed_if.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "qedi_fw_iscsi.h"
128c2ecf20Sopenharmony_ci#include "qedi_fw_scsi.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define SCSI_NUM_SGES_IN_CACHE 0x4
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cistatic bool scsi_is_slow_sgl(u16 num_sges, bool small_mid_sge)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	return (num_sges > SCSI_NUM_SGES_SLOW_SGL_THR && small_mid_sge);
198c2ecf20Sopenharmony_ci}
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_cistatic
228c2ecf20Sopenharmony_civoid init_scsi_sgl_context(struct scsi_sgl_params *ctx_sgl_params,
238c2ecf20Sopenharmony_ci			   struct scsi_cached_sges *ctx_data_desc,
248c2ecf20Sopenharmony_ci			   struct scsi_sgl_task_params *sgl_task_params)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	u8 sge_index;
278c2ecf20Sopenharmony_ci	u8 num_sges;
288c2ecf20Sopenharmony_ci	u32 val;
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci	num_sges = (sgl_task_params->num_sges > SCSI_NUM_SGES_IN_CACHE) ?
318c2ecf20Sopenharmony_ci			     SCSI_NUM_SGES_IN_CACHE : sgl_task_params->num_sges;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	/* sgl params */
348c2ecf20Sopenharmony_ci	val = cpu_to_le32(sgl_task_params->sgl_phys_addr.lo);
358c2ecf20Sopenharmony_ci	ctx_sgl_params->sgl_addr.lo = val;
368c2ecf20Sopenharmony_ci	val = cpu_to_le32(sgl_task_params->sgl_phys_addr.hi);
378c2ecf20Sopenharmony_ci	ctx_sgl_params->sgl_addr.hi = val;
388c2ecf20Sopenharmony_ci	val = cpu_to_le32(sgl_task_params->total_buffer_size);
398c2ecf20Sopenharmony_ci	ctx_sgl_params->sgl_total_length = val;
408c2ecf20Sopenharmony_ci	ctx_sgl_params->sgl_num_sges = cpu_to_le16(sgl_task_params->num_sges);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	for (sge_index = 0; sge_index < num_sges; sge_index++) {
438c2ecf20Sopenharmony_ci		val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_addr.lo);
448c2ecf20Sopenharmony_ci		ctx_data_desc->sge[sge_index].sge_addr.lo = val;
458c2ecf20Sopenharmony_ci		val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_addr.hi);
468c2ecf20Sopenharmony_ci		ctx_data_desc->sge[sge_index].sge_addr.hi = val;
478c2ecf20Sopenharmony_ci		val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_len);
488c2ecf20Sopenharmony_ci		ctx_data_desc->sge[sge_index].sge_len = val;
498c2ecf20Sopenharmony_ci	}
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic u32 calc_rw_task_size(struct iscsi_task_params *task_params,
538c2ecf20Sopenharmony_ci			     enum iscsi_task_type task_type,
548c2ecf20Sopenharmony_ci			     struct scsi_sgl_task_params *sgl_task_params,
558c2ecf20Sopenharmony_ci			     struct scsi_dif_task_params *dif_task_params)
568c2ecf20Sopenharmony_ci{
578c2ecf20Sopenharmony_ci	u32 io_size;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	if (task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE ||
608c2ecf20Sopenharmony_ci	    task_type == ISCSI_TASK_TYPE_TARGET_READ)
618c2ecf20Sopenharmony_ci		io_size = task_params->tx_io_size;
628c2ecf20Sopenharmony_ci	else
638c2ecf20Sopenharmony_ci		io_size = task_params->rx_io_size;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	if (!io_size)
668c2ecf20Sopenharmony_ci		return 0;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	if (!dif_task_params)
698c2ecf20Sopenharmony_ci		return io_size;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	return !dif_task_params->dif_on_network ?
728c2ecf20Sopenharmony_ci	       io_size : sgl_task_params->total_buffer_size;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic void
768c2ecf20Sopenharmony_ciinit_dif_context_flags(struct iscsi_dif_flags *ctx_dif_flags,
778c2ecf20Sopenharmony_ci		       struct scsi_dif_task_params *dif_task_params)
788c2ecf20Sopenharmony_ci{
798c2ecf20Sopenharmony_ci	if (!dif_task_params)
808c2ecf20Sopenharmony_ci		return;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_PROT_INTERVAL_SIZE_LOG,
838c2ecf20Sopenharmony_ci		  dif_task_params->dif_block_size_log);
848c2ecf20Sopenharmony_ci	SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_DIF_TO_PEER,
858c2ecf20Sopenharmony_ci		  dif_task_params->dif_on_network ? 1 : 0);
868c2ecf20Sopenharmony_ci	SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_HOST_INTERFACE,
878c2ecf20Sopenharmony_ci		  dif_task_params->dif_on_host ? 1 : 0);
888c2ecf20Sopenharmony_ci}
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic void init_sqe(struct iscsi_task_params *task_params,
918c2ecf20Sopenharmony_ci		     struct scsi_sgl_task_params *sgl_task_params,
928c2ecf20Sopenharmony_ci		     struct scsi_dif_task_params *dif_task_params,
938c2ecf20Sopenharmony_ci		     struct iscsi_common_hdr *pdu_header,
948c2ecf20Sopenharmony_ci		     struct scsi_initiator_cmd_params *cmd_params,
958c2ecf20Sopenharmony_ci		     enum iscsi_task_type task_type,
968c2ecf20Sopenharmony_ci		     bool is_cleanup)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	if (!task_params->sqe)
998c2ecf20Sopenharmony_ci		return;
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	memset(task_params->sqe, 0, sizeof(*task_params->sqe));
1028c2ecf20Sopenharmony_ci	task_params->sqe->task_id = cpu_to_le16(task_params->itid);
1038c2ecf20Sopenharmony_ci	if (is_cleanup) {
1048c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
1058c2ecf20Sopenharmony_ci			  ISCSI_WQE_TYPE_TASK_CLEANUP);
1068c2ecf20Sopenharmony_ci		return;
1078c2ecf20Sopenharmony_ci	}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	switch (task_type) {
1108c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_INITIATOR_WRITE:
1118c2ecf20Sopenharmony_ci	{
1128c2ecf20Sopenharmony_ci		u32 buf_size = 0;
1138c2ecf20Sopenharmony_ci		u32 num_sges = 0;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci		init_dif_context_flags(&task_params->sqe->prot_flags,
1168c2ecf20Sopenharmony_ci				       dif_task_params);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
1198c2ecf20Sopenharmony_ci			  ISCSI_WQE_TYPE_NORMAL);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci		if (task_params->tx_io_size) {
1228c2ecf20Sopenharmony_ci			buf_size = calc_rw_task_size(task_params, task_type,
1238c2ecf20Sopenharmony_ci						     sgl_task_params,
1248c2ecf20Sopenharmony_ci						     dif_task_params);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci			if (scsi_is_slow_sgl(sgl_task_params->num_sges,
1278c2ecf20Sopenharmony_ci					     sgl_task_params->small_mid_sge))
1288c2ecf20Sopenharmony_ci				num_sges = ISCSI_WQE_NUM_SGES_SLOWIO;
1298c2ecf20Sopenharmony_ci			else
1308c2ecf20Sopenharmony_ci				num_sges = min(sgl_task_params->num_sges,
1318c2ecf20Sopenharmony_ci					       (u16)SCSI_NUM_SGES_SLOW_SGL_THR);
1328c2ecf20Sopenharmony_ci		}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
1358c2ecf20Sopenharmony_ci			  num_sges);
1368c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->contlen_cdbsize, ISCSI_WQE_CONT_LEN,
1378c2ecf20Sopenharmony_ci			  buf_size);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci		if (GET_FIELD(pdu_header->hdr_second_dword,
1408c2ecf20Sopenharmony_ci			      ISCSI_CMD_HDR_TOTAL_AHS_LEN))
1418c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->contlen_cdbsize,
1428c2ecf20Sopenharmony_ci				  ISCSI_WQE_CDB_SIZE,
1438c2ecf20Sopenharmony_ci				  cmd_params->extended_cdb_sge.sge_len);
1448c2ecf20Sopenharmony_ci	}
1458c2ecf20Sopenharmony_ci		break;
1468c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_INITIATOR_READ:
1478c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
1488c2ecf20Sopenharmony_ci			  ISCSI_WQE_TYPE_NORMAL);
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci		if (GET_FIELD(pdu_header->hdr_second_dword,
1518c2ecf20Sopenharmony_ci			      ISCSI_CMD_HDR_TOTAL_AHS_LEN))
1528c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->contlen_cdbsize,
1538c2ecf20Sopenharmony_ci				  ISCSI_WQE_CDB_SIZE,
1548c2ecf20Sopenharmony_ci				  cmd_params->extended_cdb_sge.sge_len);
1558c2ecf20Sopenharmony_ci		break;
1568c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_LOGIN_RESPONSE:
1578c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_MIDPATH:
1588c2ecf20Sopenharmony_ci	{
1598c2ecf20Sopenharmony_ci		bool advance_statsn = true;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci		if (task_type == ISCSI_TASK_TYPE_LOGIN_RESPONSE)
1628c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
1638c2ecf20Sopenharmony_ci				  ISCSI_WQE_TYPE_LOGIN);
1648c2ecf20Sopenharmony_ci		else
1658c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
1668c2ecf20Sopenharmony_ci				  ISCSI_WQE_TYPE_MIDDLE_PATH);
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci		if (task_type == ISCSI_TASK_TYPE_MIDPATH) {
1698c2ecf20Sopenharmony_ci			u8 opcode = GET_FIELD(pdu_header->hdr_first_byte,
1708c2ecf20Sopenharmony_ci					      ISCSI_COMMON_HDR_OPCODE);
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci			if (opcode != ISCSI_OPCODE_TEXT_RESPONSE &&
1738c2ecf20Sopenharmony_ci			    (opcode != ISCSI_OPCODE_NOP_IN ||
1748c2ecf20Sopenharmony_ci			    pdu_header->itt == ISCSI_TTT_ALL_ONES))
1758c2ecf20Sopenharmony_ci				advance_statsn = false;
1768c2ecf20Sopenharmony_ci		}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci		SET_FIELD(task_params->sqe->flags, ISCSI_WQE_RESPONSE,
1798c2ecf20Sopenharmony_ci			  advance_statsn ? 1 : 0);
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci		if (task_params->tx_io_size) {
1828c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->contlen_cdbsize,
1838c2ecf20Sopenharmony_ci				  ISCSI_WQE_CONT_LEN, task_params->tx_io_size);
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci		if (scsi_is_slow_sgl(sgl_task_params->num_sges,
1868c2ecf20Sopenharmony_ci				     sgl_task_params->small_mid_sge))
1878c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
1888c2ecf20Sopenharmony_ci				  ISCSI_WQE_NUM_SGES_SLOWIO);
1898c2ecf20Sopenharmony_ci		else
1908c2ecf20Sopenharmony_ci			SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
1918c2ecf20Sopenharmony_ci				  min(sgl_task_params->num_sges,
1928c2ecf20Sopenharmony_ci				      (u16)SCSI_NUM_SGES_SLOW_SGL_THR));
1938c2ecf20Sopenharmony_ci		}
1948c2ecf20Sopenharmony_ci	}
1958c2ecf20Sopenharmony_ci		break;
1968c2ecf20Sopenharmony_ci	default:
1978c2ecf20Sopenharmony_ci		break;
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistatic void init_default_iscsi_task(struct iscsi_task_params *task_params,
2028c2ecf20Sopenharmony_ci				    struct data_hdr *pdu_header,
2038c2ecf20Sopenharmony_ci				    enum iscsi_task_type task_type)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *context;
2068c2ecf20Sopenharmony_ci	u32 val;
2078c2ecf20Sopenharmony_ci	u16 index;
2088c2ecf20Sopenharmony_ci	u8 val_byte;
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci	context = task_params->context;
2118c2ecf20Sopenharmony_ci	val_byte = context->mstorm_ag_context.cdu_validation;
2128c2ecf20Sopenharmony_ci	memset(context, 0, sizeof(*context));
2138c2ecf20Sopenharmony_ci	context->mstorm_ag_context.cdu_validation = val_byte;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	for (index = 0; index <
2168c2ecf20Sopenharmony_ci	     ARRAY_SIZE(context->ystorm_st_context.pdu_hdr.data.data);
2178c2ecf20Sopenharmony_ci	     index++) {
2188c2ecf20Sopenharmony_ci		val = cpu_to_le32(pdu_header->data[index]);
2198c2ecf20Sopenharmony_ci		context->ystorm_st_context.pdu_hdr.data.data[index] = val;
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	context->mstorm_st_context.task_type = task_type;
2238c2ecf20Sopenharmony_ci	context->mstorm_ag_context.task_cid =
2248c2ecf20Sopenharmony_ci					    cpu_to_le16(task_params->conn_icid);
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ci	SET_FIELD(context->ustorm_ag_context.flags1,
2278c2ecf20Sopenharmony_ci		  E4_USTORM_ISCSI_TASK_AG_CTX_R2T2RECV, 1);
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	context->ustorm_st_context.task_type = task_type;
2308c2ecf20Sopenharmony_ci	context->ustorm_st_context.cq_rss_number = task_params->cq_rss_number;
2318c2ecf20Sopenharmony_ci	context->ustorm_ag_context.icid = cpu_to_le16(task_params->conn_icid);
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic
2358c2ecf20Sopenharmony_civoid init_initiator_rw_cdb_ystorm_context(struct ystorm_iscsi_task_st_ctx *ystc,
2368c2ecf20Sopenharmony_ci					  struct scsi_initiator_cmd_params *cmd)
2378c2ecf20Sopenharmony_ci{
2388c2ecf20Sopenharmony_ci	union iscsi_task_hdr *ctx_pdu_hdr = &ystc->pdu_hdr;
2398c2ecf20Sopenharmony_ci	u32 val;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci	if (!cmd->extended_cdb_sge.sge_len)
2428c2ecf20Sopenharmony_ci		return;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	SET_FIELD(ctx_pdu_hdr->ext_cdb_cmd.hdr_second_dword,
2458c2ecf20Sopenharmony_ci		  ISCSI_EXT_CDB_CMD_HDR_CDB_SIZE,
2468c2ecf20Sopenharmony_ci		  cmd->extended_cdb_sge.sge_len);
2478c2ecf20Sopenharmony_ci	val = cpu_to_le32(cmd->extended_cdb_sge.sge_addr.lo);
2488c2ecf20Sopenharmony_ci	ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_addr.lo = val;
2498c2ecf20Sopenharmony_ci	val = cpu_to_le32(cmd->extended_cdb_sge.sge_addr.hi);
2508c2ecf20Sopenharmony_ci	ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_addr.hi = val;
2518c2ecf20Sopenharmony_ci	val = cpu_to_le32(cmd->extended_cdb_sge.sge_len);
2528c2ecf20Sopenharmony_ci	ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_len  = val;
2538c2ecf20Sopenharmony_ci}
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_cistatic
2568c2ecf20Sopenharmony_civoid init_ustorm_task_contexts(struct ustorm_iscsi_task_st_ctx *ustorm_st_cxt,
2578c2ecf20Sopenharmony_ci			struct e4_ustorm_iscsi_task_ag_ctx *ustorm_ag_cxt,
2588c2ecf20Sopenharmony_ci			u32 remaining_recv_len, u32 expected_data_transfer_len,
2598c2ecf20Sopenharmony_ci			u8 num_sges, bool tx_dif_conn_err_en)
2608c2ecf20Sopenharmony_ci{
2618c2ecf20Sopenharmony_ci	u32 val;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	ustorm_st_cxt->rem_rcv_len = cpu_to_le32(remaining_recv_len);
2648c2ecf20Sopenharmony_ci	ustorm_ag_cxt->exp_data_acked = cpu_to_le32(expected_data_transfer_len);
2658c2ecf20Sopenharmony_ci	val = cpu_to_le32(expected_data_transfer_len);
2668c2ecf20Sopenharmony_ci	ustorm_st_cxt->exp_data_transfer_len = val;
2678c2ecf20Sopenharmony_ci	SET_FIELD(ustorm_st_cxt->reg1.reg1_map, ISCSI_REG1_NUM_SGES, num_sges);
2688c2ecf20Sopenharmony_ci	SET_FIELD(ustorm_ag_cxt->flags2,
2698c2ecf20Sopenharmony_ci		  E4_USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_EN,
2708c2ecf20Sopenharmony_ci		  tx_dif_conn_err_en ? 1 : 0);
2718c2ecf20Sopenharmony_ci}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_cistatic
2748c2ecf20Sopenharmony_civoid set_rw_exp_data_acked_and_cont_len(struct e4_iscsi_task_context *context,
2758c2ecf20Sopenharmony_ci					struct iscsi_conn_params  *conn_params,
2768c2ecf20Sopenharmony_ci					enum iscsi_task_type task_type,
2778c2ecf20Sopenharmony_ci					u32 task_size,
2788c2ecf20Sopenharmony_ci					u32 exp_data_transfer_len,
2798c2ecf20Sopenharmony_ci					u8 total_ahs_length)
2808c2ecf20Sopenharmony_ci{
2818c2ecf20Sopenharmony_ci	u32 max_unsolicited_data = 0, val;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if (total_ahs_length &&
2848c2ecf20Sopenharmony_ci	    (task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE ||
2858c2ecf20Sopenharmony_ci	     task_type == ISCSI_TASK_TYPE_INITIATOR_READ))
2868c2ecf20Sopenharmony_ci		SET_FIELD(context->ustorm_st_context.flags2,
2878c2ecf20Sopenharmony_ci			  USTORM_ISCSI_TASK_ST_CTX_AHS_EXIST, 1);
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci	switch (task_type) {
2908c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_INITIATOR_WRITE:
2918c2ecf20Sopenharmony_ci		if (!conn_params->initial_r2t)
2928c2ecf20Sopenharmony_ci			max_unsolicited_data = conn_params->first_burst_length;
2938c2ecf20Sopenharmony_ci		else if (conn_params->immediate_data)
2948c2ecf20Sopenharmony_ci			max_unsolicited_data =
2958c2ecf20Sopenharmony_ci					  min(conn_params->first_burst_length,
2968c2ecf20Sopenharmony_ci					      conn_params->max_send_pdu_length);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci		context->ustorm_ag_context.exp_data_acked =
2998c2ecf20Sopenharmony_ci				   cpu_to_le32(total_ahs_length == 0 ?
3008c2ecf20Sopenharmony_ci						min(exp_data_transfer_len,
3018c2ecf20Sopenharmony_ci						    max_unsolicited_data) :
3028c2ecf20Sopenharmony_ci						((u32)(total_ahs_length +
3038c2ecf20Sopenharmony_ci						       ISCSI_AHS_CNTL_SIZE)));
3048c2ecf20Sopenharmony_ci		break;
3058c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_TARGET_READ:
3068c2ecf20Sopenharmony_ci		val = cpu_to_le32(exp_data_transfer_len);
3078c2ecf20Sopenharmony_ci		context->ustorm_ag_context.exp_data_acked = val;
3088c2ecf20Sopenharmony_ci		break;
3098c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_INITIATOR_READ:
3108c2ecf20Sopenharmony_ci		context->ustorm_ag_context.exp_data_acked =
3118c2ecf20Sopenharmony_ci					cpu_to_le32((total_ahs_length == 0 ? 0 :
3128c2ecf20Sopenharmony_ci						     total_ahs_length +
3138c2ecf20Sopenharmony_ci						     ISCSI_AHS_CNTL_SIZE));
3148c2ecf20Sopenharmony_ci		break;
3158c2ecf20Sopenharmony_ci	case ISCSI_TASK_TYPE_TARGET_WRITE:
3168c2ecf20Sopenharmony_ci		val = cpu_to_le32(task_size);
3178c2ecf20Sopenharmony_ci		context->ustorm_ag_context.exp_cont_len = val;
3188c2ecf20Sopenharmony_ci		break;
3198c2ecf20Sopenharmony_ci	default:
3208c2ecf20Sopenharmony_ci		break;
3218c2ecf20Sopenharmony_ci	}
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic
3258c2ecf20Sopenharmony_civoid init_rtdif_task_context(struct rdif_task_context *rdif_context,
3268c2ecf20Sopenharmony_ci			     struct tdif_task_context *tdif_context,
3278c2ecf20Sopenharmony_ci			     struct scsi_dif_task_params *dif_task_params,
3288c2ecf20Sopenharmony_ci			     enum iscsi_task_type task_type)
3298c2ecf20Sopenharmony_ci{
3308c2ecf20Sopenharmony_ci	u32 val;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	if (!dif_task_params->dif_on_network || !dif_task_params->dif_on_host)
3338c2ecf20Sopenharmony_ci		return;
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	if (task_type == ISCSI_TASK_TYPE_TARGET_WRITE ||
3368c2ecf20Sopenharmony_ci	    task_type == ISCSI_TASK_TYPE_INITIATOR_READ) {
3378c2ecf20Sopenharmony_ci		rdif_context->app_tag_value =
3388c2ecf20Sopenharmony_ci				  cpu_to_le16(dif_task_params->application_tag);
3398c2ecf20Sopenharmony_ci		rdif_context->partial_crc_value = cpu_to_le16(0xffff);
3408c2ecf20Sopenharmony_ci		val = cpu_to_le32(dif_task_params->initial_ref_tag);
3418c2ecf20Sopenharmony_ci		rdif_context->initial_ref_tag = val;
3428c2ecf20Sopenharmony_ci		rdif_context->app_tag_mask =
3438c2ecf20Sopenharmony_ci			     cpu_to_le16(dif_task_params->application_tag_mask);
3448c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags0, RDIF_TASK_CONTEXT_CRC_SEED,
3458c2ecf20Sopenharmony_ci			  dif_task_params->crc_seed ? 1 : 0);
3468c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags0,
3478c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_HOST_GUARD_TYPE,
3488c2ecf20Sopenharmony_ci			  dif_task_params->host_guard_type);
3498c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags0,
3508c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_PROTECTION_TYPE,
3518c2ecf20Sopenharmony_ci			  dif_task_params->protection_type);
3528c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags0,
3538c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_INITIAL_REF_TAG_VALID, 1);
3548c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags0,
3558c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_KEEP_REF_TAG_CONST,
3568c2ecf20Sopenharmony_ci			  dif_task_params->keep_ref_tag_const ? 1 : 0);
3578c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3588c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_VALIDATE_APP_TAG,
3598c2ecf20Sopenharmony_ci			  (dif_task_params->validate_app_tag &&
3608c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_network) ? 1 : 0);
3618c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3628c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_VALIDATE_GUARD,
3638c2ecf20Sopenharmony_ci			  (dif_task_params->validate_guard &&
3648c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_network) ? 1 : 0);
3658c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3668c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_VALIDATE_REF_TAG,
3678c2ecf20Sopenharmony_ci			  (dif_task_params->validate_ref_tag &&
3688c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_network) ? 1 : 0);
3698c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3708c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_HOST_INTERFACE,
3718c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_host ? 1 : 0);
3728c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3738c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_NETWORK_INTERFACE,
3748c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_network ? 1 : 0);
3758c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3768c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_FORWARD_GUARD,
3778c2ecf20Sopenharmony_ci			  dif_task_params->forward_guard ? 1 : 0);
3788c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3798c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_FORWARD_APP_TAG,
3808c2ecf20Sopenharmony_ci			  dif_task_params->forward_app_tag ? 1 : 0);
3818c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3828c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_FORWARD_REF_TAG,
3838c2ecf20Sopenharmony_ci			  dif_task_params->forward_ref_tag ? 1 : 0);
3848c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3858c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_FORWARD_APP_TAG_WITH_MASK,
3868c2ecf20Sopenharmony_ci			  dif_task_params->forward_app_tag_with_mask ? 1 : 0);
3878c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3888c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_FORWARD_REF_TAG_WITH_MASK,
3898c2ecf20Sopenharmony_ci			  dif_task_params->forward_ref_tag_with_mask ? 1 : 0);
3908c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->flags1,
3918c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_INTERVAL_SIZE,
3928c2ecf20Sopenharmony_ci			  dif_task_params->dif_block_size_log - 9);
3938c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->state,
3948c2ecf20Sopenharmony_ci			  RDIF_TASK_CONTEXT_REF_TAG_MASK,
3958c2ecf20Sopenharmony_ci			  dif_task_params->ref_tag_mask);
3968c2ecf20Sopenharmony_ci		SET_FIELD(rdif_context->state, RDIF_TASK_CONTEXT_IGNORE_APP_TAG,
3978c2ecf20Sopenharmony_ci			  dif_task_params->ignore_app_tag);
3988c2ecf20Sopenharmony_ci	}
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	if (task_type == ISCSI_TASK_TYPE_TARGET_READ ||
4018c2ecf20Sopenharmony_ci	    task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE) {
4028c2ecf20Sopenharmony_ci		tdif_context->app_tag_value =
4038c2ecf20Sopenharmony_ci				  cpu_to_le16(dif_task_params->application_tag);
4048c2ecf20Sopenharmony_ci		tdif_context->partial_crc_value_b =
4058c2ecf20Sopenharmony_ci		       cpu_to_le16(dif_task_params->crc_seed ? 0xffff : 0x0000);
4068c2ecf20Sopenharmony_ci		tdif_context->partial_crc_value_a =
4078c2ecf20Sopenharmony_ci		       cpu_to_le16(dif_task_params->crc_seed ? 0xffff : 0x0000);
4088c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0, TDIF_TASK_CONTEXT_CRC_SEED,
4098c2ecf20Sopenharmony_ci			  dif_task_params->crc_seed ? 1 : 0);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4128c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_SET_ERROR_WITH_EOP,
4138c2ecf20Sopenharmony_ci			  dif_task_params->tx_dif_conn_err_en ? 1 : 0);
4148c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1, TDIF_TASK_CONTEXT_FORWARD_GUARD,
4158c2ecf20Sopenharmony_ci			  dif_task_params->forward_guard   ? 1 : 0);
4168c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4178c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_FORWARD_APP_TAG,
4188c2ecf20Sopenharmony_ci			  dif_task_params->forward_app_tag ? 1 : 0);
4198c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4208c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_FORWARD_REF_TAG,
4218c2ecf20Sopenharmony_ci			  dif_task_params->forward_ref_tag ? 1 : 0);
4228c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1, TDIF_TASK_CONTEXT_INTERVAL_SIZE,
4238c2ecf20Sopenharmony_ci			  dif_task_params->dif_block_size_log - 9);
4248c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4258c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_HOST_INTERFACE,
4268c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_host    ? 1 : 0);
4278c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4288c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_NETWORK_INTERFACE,
4298c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_network ? 1 : 0);
4308c2ecf20Sopenharmony_ci		val = cpu_to_le32(dif_task_params->initial_ref_tag);
4318c2ecf20Sopenharmony_ci		tdif_context->initial_ref_tag = val;
4328c2ecf20Sopenharmony_ci		tdif_context->app_tag_mask =
4338c2ecf20Sopenharmony_ci			     cpu_to_le16(dif_task_params->application_tag_mask);
4348c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4358c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_HOST_GUARD_TYPE,
4368c2ecf20Sopenharmony_ci			  dif_task_params->host_guard_type);
4378c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4388c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_PROTECTION_TYPE,
4398c2ecf20Sopenharmony_ci			  dif_task_params->protection_type);
4408c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4418c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_INITIAL_REF_TAG_VALID,
4428c2ecf20Sopenharmony_ci			  dif_task_params->initial_ref_tag_is_valid ? 1 : 0);
4438c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4448c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_KEEP_REF_TAG_CONST,
4458c2ecf20Sopenharmony_ci			  dif_task_params->keep_ref_tag_const ? 1 : 0);
4468c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4478c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_VALIDATE_GUARD,
4488c2ecf20Sopenharmony_ci			  (dif_task_params->validate_guard &&
4498c2ecf20Sopenharmony_ci			   dif_task_params->dif_on_host) ? 1 : 0);
4508c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4518c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_VALIDATE_APP_TAG,
4528c2ecf20Sopenharmony_ci			  (dif_task_params->validate_app_tag &&
4538c2ecf20Sopenharmony_ci			  dif_task_params->dif_on_host) ? 1 : 0);
4548c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4558c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_VALIDATE_REF_TAG,
4568c2ecf20Sopenharmony_ci			  (dif_task_params->validate_ref_tag &&
4578c2ecf20Sopenharmony_ci			   dif_task_params->dif_on_host) ? 1 : 0);
4588c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4598c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_FORWARD_APP_TAG_WITH_MASK,
4608c2ecf20Sopenharmony_ci			  dif_task_params->forward_app_tag_with_mask ? 1 : 0);
4618c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4628c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_FORWARD_REF_TAG_WITH_MASK,
4638c2ecf20Sopenharmony_ci			  dif_task_params->forward_ref_tag_with_mask ? 1 : 0);
4648c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags1,
4658c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_REF_TAG_MASK,
4668c2ecf20Sopenharmony_ci			  dif_task_params->ref_tag_mask);
4678c2ecf20Sopenharmony_ci		SET_FIELD(tdif_context->flags0,
4688c2ecf20Sopenharmony_ci			  TDIF_TASK_CONTEXT_IGNORE_APP_TAG,
4698c2ecf20Sopenharmony_ci			  dif_task_params->ignore_app_tag ? 1 : 0);
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci}
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_cistatic void set_local_completion_context(struct e4_iscsi_task_context *context)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	SET_FIELD(context->ystorm_st_context.state.flags,
4768c2ecf20Sopenharmony_ci		  YSTORM_ISCSI_TASK_STATE_LOCAL_COMP, 1);
4778c2ecf20Sopenharmony_ci	SET_FIELD(context->ustorm_st_context.flags,
4788c2ecf20Sopenharmony_ci		  USTORM_ISCSI_TASK_ST_CTX_LOCAL_COMP, 1);
4798c2ecf20Sopenharmony_ci}
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_cistatic int init_rw_iscsi_task(struct iscsi_task_params *task_params,
4828c2ecf20Sopenharmony_ci			      enum iscsi_task_type task_type,
4838c2ecf20Sopenharmony_ci			      struct iscsi_conn_params *conn_params,
4848c2ecf20Sopenharmony_ci			      struct iscsi_common_hdr *pdu_header,
4858c2ecf20Sopenharmony_ci			      struct scsi_sgl_task_params *sgl_task_params,
4868c2ecf20Sopenharmony_ci			      struct scsi_initiator_cmd_params *cmd_params,
4878c2ecf20Sopenharmony_ci			      struct scsi_dif_task_params *dif_task_params)
4888c2ecf20Sopenharmony_ci{
4898c2ecf20Sopenharmony_ci	u32 exp_data_transfer_len = conn_params->max_burst_length;
4908c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *cxt;
4918c2ecf20Sopenharmony_ci	bool slow_io = false;
4928c2ecf20Sopenharmony_ci	u32 task_size, val;
4938c2ecf20Sopenharmony_ci	u8 num_sges = 0;
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	task_size = calc_rw_task_size(task_params, task_type, sgl_task_params,
4968c2ecf20Sopenharmony_ci				      dif_task_params);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params, (struct data_hdr *)pdu_header,
4998c2ecf20Sopenharmony_ci				task_type);
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	cxt = task_params->context;
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci	if (task_type == ISCSI_TASK_TYPE_TARGET_READ) {
5058c2ecf20Sopenharmony_ci		set_local_completion_context(cxt);
5068c2ecf20Sopenharmony_ci	} else if (task_type == ISCSI_TASK_TYPE_TARGET_WRITE) {
5078c2ecf20Sopenharmony_ci		val = cpu_to_le32(task_size +
5088c2ecf20Sopenharmony_ci			   ((struct iscsi_r2t_hdr *)pdu_header)->buffer_offset);
5098c2ecf20Sopenharmony_ci		cxt->ystorm_st_context.pdu_hdr.r2t.desired_data_trns_len = val;
5108c2ecf20Sopenharmony_ci		cxt->mstorm_st_context.expected_itt =
5118c2ecf20Sopenharmony_ci						   cpu_to_le32(pdu_header->itt);
5128c2ecf20Sopenharmony_ci	} else {
5138c2ecf20Sopenharmony_ci		val = cpu_to_le32(task_size);
5148c2ecf20Sopenharmony_ci		cxt->ystorm_st_context.pdu_hdr.cmd.expected_transfer_length =
5158c2ecf20Sopenharmony_ci									    val;
5168c2ecf20Sopenharmony_ci		init_initiator_rw_cdb_ystorm_context(&cxt->ystorm_st_context,
5178c2ecf20Sopenharmony_ci						     cmd_params);
5188c2ecf20Sopenharmony_ci		val = cpu_to_le32(cmd_params->sense_data_buffer_phys_addr.lo);
5198c2ecf20Sopenharmony_ci		cxt->mstorm_st_context.sense_db.lo = val;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci		val = cpu_to_le32(cmd_params->sense_data_buffer_phys_addr.hi);
5228c2ecf20Sopenharmony_ci		cxt->mstorm_st_context.sense_db.hi = val;
5238c2ecf20Sopenharmony_ci	}
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci	if (task_params->tx_io_size) {
5268c2ecf20Sopenharmony_ci		init_dif_context_flags(&cxt->ystorm_st_context.state.dif_flags,
5278c2ecf20Sopenharmony_ci				       dif_task_params);
5288c2ecf20Sopenharmony_ci		init_dif_context_flags(&cxt->ustorm_st_context.dif_flags,
5298c2ecf20Sopenharmony_ci				       dif_task_params);
5308c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
5318c2ecf20Sopenharmony_ci				      &cxt->ystorm_st_context.state.data_desc,
5328c2ecf20Sopenharmony_ci				      sgl_task_params);
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci		slow_io = scsi_is_slow_sgl(sgl_task_params->num_sges,
5358c2ecf20Sopenharmony_ci					   sgl_task_params->small_mid_sge);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci		num_sges = !slow_io ? min_t(u16, sgl_task_params->num_sges,
5388c2ecf20Sopenharmony_ci					    (u16)SCSI_NUM_SGES_SLOW_SGL_THR) :
5398c2ecf20Sopenharmony_ci				      ISCSI_WQE_NUM_SGES_SLOWIO;
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci		if (slow_io) {
5428c2ecf20Sopenharmony_ci			SET_FIELD(cxt->ystorm_st_context.state.flags,
5438c2ecf20Sopenharmony_ci				  YSTORM_ISCSI_TASK_STATE_SLOW_IO, 1);
5448c2ecf20Sopenharmony_ci		}
5458c2ecf20Sopenharmony_ci	} else if (task_params->rx_io_size) {
5468c2ecf20Sopenharmony_ci		init_dif_context_flags(&cxt->mstorm_st_context.dif_flags,
5478c2ecf20Sopenharmony_ci				       dif_task_params);
5488c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
5498c2ecf20Sopenharmony_ci				      &cxt->mstorm_st_context.data_desc,
5508c2ecf20Sopenharmony_ci				      sgl_task_params);
5518c2ecf20Sopenharmony_ci		num_sges = !scsi_is_slow_sgl(sgl_task_params->num_sges,
5528c2ecf20Sopenharmony_ci				sgl_task_params->small_mid_sge) ?
5538c2ecf20Sopenharmony_ci				min_t(u16, sgl_task_params->num_sges,
5548c2ecf20Sopenharmony_ci				      (u16)SCSI_NUM_SGES_SLOW_SGL_THR) :
5558c2ecf20Sopenharmony_ci				ISCSI_WQE_NUM_SGES_SLOWIO;
5568c2ecf20Sopenharmony_ci		cxt->mstorm_st_context.rem_task_size = cpu_to_le32(task_size);
5578c2ecf20Sopenharmony_ci	}
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci	if (exp_data_transfer_len > task_size  ||
5608c2ecf20Sopenharmony_ci	    task_type != ISCSI_TASK_TYPE_TARGET_WRITE)
5618c2ecf20Sopenharmony_ci		exp_data_transfer_len = task_size;
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	init_ustorm_task_contexts(&task_params->context->ustorm_st_context,
5648c2ecf20Sopenharmony_ci				  &task_params->context->ustorm_ag_context,
5658c2ecf20Sopenharmony_ci				  task_size, exp_data_transfer_len, num_sges,
5668c2ecf20Sopenharmony_ci				  dif_task_params ?
5678c2ecf20Sopenharmony_ci				  dif_task_params->tx_dif_conn_err_en : false);
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	set_rw_exp_data_acked_and_cont_len(task_params->context, conn_params,
5708c2ecf20Sopenharmony_ci					   task_type, task_size,
5718c2ecf20Sopenharmony_ci					   exp_data_transfer_len,
5728c2ecf20Sopenharmony_ci					GET_FIELD(pdu_header->hdr_second_dword,
5738c2ecf20Sopenharmony_ci						  ISCSI_CMD_HDR_TOTAL_AHS_LEN));
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_ci	if (dif_task_params)
5768c2ecf20Sopenharmony_ci		init_rtdif_task_context(&task_params->context->rdif_context,
5778c2ecf20Sopenharmony_ci					&task_params->context->tdif_context,
5788c2ecf20Sopenharmony_ci					dif_task_params, task_type);
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	init_sqe(task_params, sgl_task_params, dif_task_params, pdu_header,
5818c2ecf20Sopenharmony_ci		 cmd_params, task_type, false);
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	return 0;
5848c2ecf20Sopenharmony_ci}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_ciint init_initiator_rw_iscsi_task(struct iscsi_task_params *task_params,
5878c2ecf20Sopenharmony_ci				 struct iscsi_conn_params *conn_params,
5888c2ecf20Sopenharmony_ci				 struct scsi_initiator_cmd_params *cmd_params,
5898c2ecf20Sopenharmony_ci				 struct iscsi_cmd_hdr *cmd_header,
5908c2ecf20Sopenharmony_ci				 struct scsi_sgl_task_params *tx_sgl_params,
5918c2ecf20Sopenharmony_ci				 struct scsi_sgl_task_params *rx_sgl_params,
5928c2ecf20Sopenharmony_ci				 struct scsi_dif_task_params *dif_task_params)
5938c2ecf20Sopenharmony_ci{
5948c2ecf20Sopenharmony_ci	if (GET_FIELD(cmd_header->flags_attr, ISCSI_CMD_HDR_WRITE))
5958c2ecf20Sopenharmony_ci		return init_rw_iscsi_task(task_params,
5968c2ecf20Sopenharmony_ci					  ISCSI_TASK_TYPE_INITIATOR_WRITE,
5978c2ecf20Sopenharmony_ci					  conn_params,
5988c2ecf20Sopenharmony_ci					  (struct iscsi_common_hdr *)cmd_header,
5998c2ecf20Sopenharmony_ci					  tx_sgl_params, cmd_params,
6008c2ecf20Sopenharmony_ci					  dif_task_params);
6018c2ecf20Sopenharmony_ci	else if (GET_FIELD(cmd_header->flags_attr, ISCSI_CMD_HDR_READ) ||
6028c2ecf20Sopenharmony_ci		 (task_params->rx_io_size == 0 && task_params->tx_io_size == 0))
6038c2ecf20Sopenharmony_ci		return init_rw_iscsi_task(task_params,
6048c2ecf20Sopenharmony_ci					  ISCSI_TASK_TYPE_INITIATOR_READ,
6058c2ecf20Sopenharmony_ci					  conn_params,
6068c2ecf20Sopenharmony_ci					  (struct iscsi_common_hdr *)cmd_header,
6078c2ecf20Sopenharmony_ci					  rx_sgl_params, cmd_params,
6088c2ecf20Sopenharmony_ci					  dif_task_params);
6098c2ecf20Sopenharmony_ci	else
6108c2ecf20Sopenharmony_ci		return -1;
6118c2ecf20Sopenharmony_ci}
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ciint init_initiator_login_request_task(struct iscsi_task_params *task_params,
6148c2ecf20Sopenharmony_ci				      struct iscsi_login_req_hdr  *login_header,
6158c2ecf20Sopenharmony_ci				      struct scsi_sgl_task_params *tx_params,
6168c2ecf20Sopenharmony_ci				      struct scsi_sgl_task_params *rx_params)
6178c2ecf20Sopenharmony_ci{
6188c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *cxt;
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci	cxt = task_params->context;
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params,
6238c2ecf20Sopenharmony_ci				(struct data_hdr *)login_header,
6248c2ecf20Sopenharmony_ci				ISCSI_TASK_TYPE_MIDPATH);
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	init_ustorm_task_contexts(&cxt->ustorm_st_context,
6278c2ecf20Sopenharmony_ci				  &cxt->ustorm_ag_context,
6288c2ecf20Sopenharmony_ci				  task_params->rx_io_size ?
6298c2ecf20Sopenharmony_ci				  rx_params->total_buffer_size : 0,
6308c2ecf20Sopenharmony_ci				  task_params->tx_io_size ?
6318c2ecf20Sopenharmony_ci				  tx_params->total_buffer_size : 0, 0,
6328c2ecf20Sopenharmony_ci				  0);
6338c2ecf20Sopenharmony_ci
6348c2ecf20Sopenharmony_ci	if (task_params->tx_io_size)
6358c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
6368c2ecf20Sopenharmony_ci				      &cxt->ystorm_st_context.state.data_desc,
6378c2ecf20Sopenharmony_ci				      tx_params);
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	if (task_params->rx_io_size)
6408c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
6418c2ecf20Sopenharmony_ci				      &cxt->mstorm_st_context.data_desc,
6428c2ecf20Sopenharmony_ci				      rx_params);
6438c2ecf20Sopenharmony_ci
6448c2ecf20Sopenharmony_ci	cxt->mstorm_st_context.rem_task_size =
6458c2ecf20Sopenharmony_ci			cpu_to_le32(task_params->rx_io_size ?
6468c2ecf20Sopenharmony_ci				    rx_params->total_buffer_size : 0);
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	init_sqe(task_params, tx_params, NULL,
6498c2ecf20Sopenharmony_ci		 (struct iscsi_common_hdr *)login_header, NULL,
6508c2ecf20Sopenharmony_ci		 ISCSI_TASK_TYPE_MIDPATH, false);
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	return 0;
6538c2ecf20Sopenharmony_ci}
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ciint init_initiator_nop_out_task(struct iscsi_task_params *task_params,
6568c2ecf20Sopenharmony_ci				struct iscsi_nop_out_hdr *nop_out_pdu_header,
6578c2ecf20Sopenharmony_ci				struct scsi_sgl_task_params *tx_sgl_task_params,
6588c2ecf20Sopenharmony_ci				struct scsi_sgl_task_params *rx_sgl_task_params)
6598c2ecf20Sopenharmony_ci{
6608c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *cxt;
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	cxt = task_params->context;
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params,
6658c2ecf20Sopenharmony_ci				(struct data_hdr *)nop_out_pdu_header,
6668c2ecf20Sopenharmony_ci				ISCSI_TASK_TYPE_MIDPATH);
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci	if (nop_out_pdu_header->itt == ISCSI_ITT_ALL_ONES)
6698c2ecf20Sopenharmony_ci		set_local_completion_context(task_params->context);
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	if (task_params->tx_io_size)
6728c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
6738c2ecf20Sopenharmony_ci				      &cxt->ystorm_st_context.state.data_desc,
6748c2ecf20Sopenharmony_ci				      tx_sgl_task_params);
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_ci	if (task_params->rx_io_size)
6778c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
6788c2ecf20Sopenharmony_ci				      &cxt->mstorm_st_context.data_desc,
6798c2ecf20Sopenharmony_ci				      rx_sgl_task_params);
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	init_ustorm_task_contexts(&cxt->ustorm_st_context,
6828c2ecf20Sopenharmony_ci				  &cxt->ustorm_ag_context,
6838c2ecf20Sopenharmony_ci				  task_params->rx_io_size ?
6848c2ecf20Sopenharmony_ci				  rx_sgl_task_params->total_buffer_size : 0,
6858c2ecf20Sopenharmony_ci				  task_params->tx_io_size ?
6868c2ecf20Sopenharmony_ci				  tx_sgl_task_params->total_buffer_size : 0,
6878c2ecf20Sopenharmony_ci				  0, 0);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	cxt->mstorm_st_context.rem_task_size =
6908c2ecf20Sopenharmony_ci				cpu_to_le32(task_params->rx_io_size ?
6918c2ecf20Sopenharmony_ci					rx_sgl_task_params->total_buffer_size :
6928c2ecf20Sopenharmony_ci					0);
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	init_sqe(task_params, tx_sgl_task_params, NULL,
6958c2ecf20Sopenharmony_ci		 (struct iscsi_common_hdr *)nop_out_pdu_header, NULL,
6968c2ecf20Sopenharmony_ci		 ISCSI_TASK_TYPE_MIDPATH, false);
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	return 0;
6998c2ecf20Sopenharmony_ci}
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ciint init_initiator_logout_request_task(struct iscsi_task_params *task_params,
7028c2ecf20Sopenharmony_ci				       struct iscsi_logout_req_hdr *logout_hdr,
7038c2ecf20Sopenharmony_ci				       struct scsi_sgl_task_params *tx_params,
7048c2ecf20Sopenharmony_ci				       struct scsi_sgl_task_params *rx_params)
7058c2ecf20Sopenharmony_ci{
7068c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *cxt;
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci	cxt = task_params->context;
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params,
7118c2ecf20Sopenharmony_ci				(struct data_hdr *)logout_hdr,
7128c2ecf20Sopenharmony_ci				ISCSI_TASK_TYPE_MIDPATH);
7138c2ecf20Sopenharmony_ci
7148c2ecf20Sopenharmony_ci	if (task_params->tx_io_size)
7158c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
7168c2ecf20Sopenharmony_ci				      &cxt->ystorm_st_context.state.data_desc,
7178c2ecf20Sopenharmony_ci				      tx_params);
7188c2ecf20Sopenharmony_ci
7198c2ecf20Sopenharmony_ci	if (task_params->rx_io_size)
7208c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
7218c2ecf20Sopenharmony_ci				      &cxt->mstorm_st_context.data_desc,
7228c2ecf20Sopenharmony_ci				      rx_params);
7238c2ecf20Sopenharmony_ci
7248c2ecf20Sopenharmony_ci	init_ustorm_task_contexts(&cxt->ustorm_st_context,
7258c2ecf20Sopenharmony_ci				  &cxt->ustorm_ag_context,
7268c2ecf20Sopenharmony_ci				  task_params->rx_io_size ?
7278c2ecf20Sopenharmony_ci				  rx_params->total_buffer_size : 0,
7288c2ecf20Sopenharmony_ci				  task_params->tx_io_size ?
7298c2ecf20Sopenharmony_ci				  tx_params->total_buffer_size : 0,
7308c2ecf20Sopenharmony_ci				  0, 0);
7318c2ecf20Sopenharmony_ci
7328c2ecf20Sopenharmony_ci	cxt->mstorm_st_context.rem_task_size =
7338c2ecf20Sopenharmony_ci					cpu_to_le32(task_params->rx_io_size ?
7348c2ecf20Sopenharmony_ci					rx_params->total_buffer_size : 0);
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci	init_sqe(task_params, tx_params, NULL,
7378c2ecf20Sopenharmony_ci		 (struct iscsi_common_hdr *)logout_hdr, NULL,
7388c2ecf20Sopenharmony_ci		 ISCSI_TASK_TYPE_MIDPATH, false);
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci	return 0;
7418c2ecf20Sopenharmony_ci}
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ciint init_initiator_tmf_request_task(struct iscsi_task_params *task_params,
7448c2ecf20Sopenharmony_ci				    struct iscsi_tmf_request_hdr *tmf_header)
7458c2ecf20Sopenharmony_ci{
7468c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params, (struct data_hdr *)tmf_header,
7478c2ecf20Sopenharmony_ci				ISCSI_TASK_TYPE_MIDPATH);
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_ci	init_sqe(task_params, NULL, NULL,
7508c2ecf20Sopenharmony_ci		 (struct iscsi_common_hdr *)tmf_header, NULL,
7518c2ecf20Sopenharmony_ci		 ISCSI_TASK_TYPE_MIDPATH, false);
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci	return 0;
7548c2ecf20Sopenharmony_ci}
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ciint init_initiator_text_request_task(struct iscsi_task_params *task_params,
7578c2ecf20Sopenharmony_ci				     struct iscsi_text_request_hdr *text_header,
7588c2ecf20Sopenharmony_ci				     struct scsi_sgl_task_params *tx_params,
7598c2ecf20Sopenharmony_ci				     struct scsi_sgl_task_params *rx_params)
7608c2ecf20Sopenharmony_ci{
7618c2ecf20Sopenharmony_ci	struct e4_iscsi_task_context *cxt;
7628c2ecf20Sopenharmony_ci
7638c2ecf20Sopenharmony_ci	cxt = task_params->context;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci	init_default_iscsi_task(task_params,
7668c2ecf20Sopenharmony_ci				(struct data_hdr *)text_header,
7678c2ecf20Sopenharmony_ci				ISCSI_TASK_TYPE_MIDPATH);
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_ci	if (task_params->tx_io_size)
7708c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
7718c2ecf20Sopenharmony_ci				      &cxt->ystorm_st_context.state.data_desc,
7728c2ecf20Sopenharmony_ci				      tx_params);
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci	if (task_params->rx_io_size)
7758c2ecf20Sopenharmony_ci		init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
7768c2ecf20Sopenharmony_ci				      &cxt->mstorm_st_context.data_desc,
7778c2ecf20Sopenharmony_ci				      rx_params);
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	cxt->mstorm_st_context.rem_task_size =
7808c2ecf20Sopenharmony_ci				cpu_to_le32(task_params->rx_io_size ?
7818c2ecf20Sopenharmony_ci					rx_params->total_buffer_size : 0);
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	init_ustorm_task_contexts(&cxt->ustorm_st_context,
7848c2ecf20Sopenharmony_ci				  &cxt->ustorm_ag_context,
7858c2ecf20Sopenharmony_ci				  task_params->rx_io_size ?
7868c2ecf20Sopenharmony_ci				  rx_params->total_buffer_size : 0,
7878c2ecf20Sopenharmony_ci				  task_params->tx_io_size ?
7888c2ecf20Sopenharmony_ci				  tx_params->total_buffer_size : 0, 0, 0);
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci	init_sqe(task_params, tx_params, NULL,
7918c2ecf20Sopenharmony_ci		 (struct iscsi_common_hdr *)text_header, NULL,
7928c2ecf20Sopenharmony_ci		 ISCSI_TASK_TYPE_MIDPATH, false);
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	return 0;
7958c2ecf20Sopenharmony_ci}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ciint init_cleanup_task(struct iscsi_task_params *task_params)
7988c2ecf20Sopenharmony_ci{
7998c2ecf20Sopenharmony_ci	init_sqe(task_params, NULL, NULL, NULL, NULL, ISCSI_TASK_TYPE_MIDPATH,
8008c2ecf20Sopenharmony_ci		 true);
8018c2ecf20Sopenharmony_ci	return 0;
8028c2ecf20Sopenharmony_ci}
803