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