1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /* QLogic iSCSI Offload Driver
3*4882a593Smuzhiyun * Copyright (c) 2016 Cavium Inc.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/types.h>
7*4882a593Smuzhiyun #include <asm/byteorder.h>
8*4882a593Smuzhiyun #include "qedi_hsi.h"
9*4882a593Smuzhiyun #include <linux/qed/qed_if.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include "qedi_fw_iscsi.h"
12*4882a593Smuzhiyun #include "qedi_fw_scsi.h"
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define SCSI_NUM_SGES_IN_CACHE 0x4
15*4882a593Smuzhiyun
scsi_is_slow_sgl(u16 num_sges,bool small_mid_sge)16*4882a593Smuzhiyun static bool scsi_is_slow_sgl(u16 num_sges, bool small_mid_sge)
17*4882a593Smuzhiyun {
18*4882a593Smuzhiyun return (num_sges > SCSI_NUM_SGES_SLOW_SGL_THR && small_mid_sge);
19*4882a593Smuzhiyun }
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun static
init_scsi_sgl_context(struct scsi_sgl_params * ctx_sgl_params,struct scsi_cached_sges * ctx_data_desc,struct scsi_sgl_task_params * sgl_task_params)22*4882a593Smuzhiyun void init_scsi_sgl_context(struct scsi_sgl_params *ctx_sgl_params,
23*4882a593Smuzhiyun struct scsi_cached_sges *ctx_data_desc,
24*4882a593Smuzhiyun struct scsi_sgl_task_params *sgl_task_params)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun u8 sge_index;
27*4882a593Smuzhiyun u8 num_sges;
28*4882a593Smuzhiyun u32 val;
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun num_sges = (sgl_task_params->num_sges > SCSI_NUM_SGES_IN_CACHE) ?
31*4882a593Smuzhiyun SCSI_NUM_SGES_IN_CACHE : sgl_task_params->num_sges;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun /* sgl params */
34*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->sgl_phys_addr.lo);
35*4882a593Smuzhiyun ctx_sgl_params->sgl_addr.lo = val;
36*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->sgl_phys_addr.hi);
37*4882a593Smuzhiyun ctx_sgl_params->sgl_addr.hi = val;
38*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->total_buffer_size);
39*4882a593Smuzhiyun ctx_sgl_params->sgl_total_length = val;
40*4882a593Smuzhiyun ctx_sgl_params->sgl_num_sges = cpu_to_le16(sgl_task_params->num_sges);
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun for (sge_index = 0; sge_index < num_sges; sge_index++) {
43*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_addr.lo);
44*4882a593Smuzhiyun ctx_data_desc->sge[sge_index].sge_addr.lo = val;
45*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_addr.hi);
46*4882a593Smuzhiyun ctx_data_desc->sge[sge_index].sge_addr.hi = val;
47*4882a593Smuzhiyun val = cpu_to_le32(sgl_task_params->sgl[sge_index].sge_len);
48*4882a593Smuzhiyun ctx_data_desc->sge[sge_index].sge_len = val;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun
calc_rw_task_size(struct iscsi_task_params * task_params,enum iscsi_task_type task_type,struct scsi_sgl_task_params * sgl_task_params,struct scsi_dif_task_params * dif_task_params)52*4882a593Smuzhiyun static u32 calc_rw_task_size(struct iscsi_task_params *task_params,
53*4882a593Smuzhiyun enum iscsi_task_type task_type,
54*4882a593Smuzhiyun struct scsi_sgl_task_params *sgl_task_params,
55*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun u32 io_size;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE ||
60*4882a593Smuzhiyun task_type == ISCSI_TASK_TYPE_TARGET_READ)
61*4882a593Smuzhiyun io_size = task_params->tx_io_size;
62*4882a593Smuzhiyun else
63*4882a593Smuzhiyun io_size = task_params->rx_io_size;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun if (!io_size)
66*4882a593Smuzhiyun return 0;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun if (!dif_task_params)
69*4882a593Smuzhiyun return io_size;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun return !dif_task_params->dif_on_network ?
72*4882a593Smuzhiyun io_size : sgl_task_params->total_buffer_size;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun static void
init_dif_context_flags(struct iscsi_dif_flags * ctx_dif_flags,struct scsi_dif_task_params * dif_task_params)76*4882a593Smuzhiyun init_dif_context_flags(struct iscsi_dif_flags *ctx_dif_flags,
77*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun if (!dif_task_params)
80*4882a593Smuzhiyun return;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_PROT_INTERVAL_SIZE_LOG,
83*4882a593Smuzhiyun dif_task_params->dif_block_size_log);
84*4882a593Smuzhiyun SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_DIF_TO_PEER,
85*4882a593Smuzhiyun dif_task_params->dif_on_network ? 1 : 0);
86*4882a593Smuzhiyun SET_FIELD(ctx_dif_flags->flags, ISCSI_DIF_FLAGS_HOST_INTERFACE,
87*4882a593Smuzhiyun dif_task_params->dif_on_host ? 1 : 0);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
init_sqe(struct iscsi_task_params * task_params,struct scsi_sgl_task_params * sgl_task_params,struct scsi_dif_task_params * dif_task_params,struct iscsi_common_hdr * pdu_header,struct scsi_initiator_cmd_params * cmd_params,enum iscsi_task_type task_type,bool is_cleanup)90*4882a593Smuzhiyun static void init_sqe(struct iscsi_task_params *task_params,
91*4882a593Smuzhiyun struct scsi_sgl_task_params *sgl_task_params,
92*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params,
93*4882a593Smuzhiyun struct iscsi_common_hdr *pdu_header,
94*4882a593Smuzhiyun struct scsi_initiator_cmd_params *cmd_params,
95*4882a593Smuzhiyun enum iscsi_task_type task_type,
96*4882a593Smuzhiyun bool is_cleanup)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun if (!task_params->sqe)
99*4882a593Smuzhiyun return;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun memset(task_params->sqe, 0, sizeof(*task_params->sqe));
102*4882a593Smuzhiyun task_params->sqe->task_id = cpu_to_le16(task_params->itid);
103*4882a593Smuzhiyun if (is_cleanup) {
104*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
105*4882a593Smuzhiyun ISCSI_WQE_TYPE_TASK_CLEANUP);
106*4882a593Smuzhiyun return;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun switch (task_type) {
110*4882a593Smuzhiyun case ISCSI_TASK_TYPE_INITIATOR_WRITE:
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun u32 buf_size = 0;
113*4882a593Smuzhiyun u32 num_sges = 0;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun init_dif_context_flags(&task_params->sqe->prot_flags,
116*4882a593Smuzhiyun dif_task_params);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
119*4882a593Smuzhiyun ISCSI_WQE_TYPE_NORMAL);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun if (task_params->tx_io_size) {
122*4882a593Smuzhiyun buf_size = calc_rw_task_size(task_params, task_type,
123*4882a593Smuzhiyun sgl_task_params,
124*4882a593Smuzhiyun dif_task_params);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun if (scsi_is_slow_sgl(sgl_task_params->num_sges,
127*4882a593Smuzhiyun sgl_task_params->small_mid_sge))
128*4882a593Smuzhiyun num_sges = ISCSI_WQE_NUM_SGES_SLOWIO;
129*4882a593Smuzhiyun else
130*4882a593Smuzhiyun num_sges = min(sgl_task_params->num_sges,
131*4882a593Smuzhiyun (u16)SCSI_NUM_SGES_SLOW_SGL_THR);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
135*4882a593Smuzhiyun num_sges);
136*4882a593Smuzhiyun SET_FIELD(task_params->sqe->contlen_cdbsize, ISCSI_WQE_CONT_LEN,
137*4882a593Smuzhiyun buf_size);
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (GET_FIELD(pdu_header->hdr_second_dword,
140*4882a593Smuzhiyun ISCSI_CMD_HDR_TOTAL_AHS_LEN))
141*4882a593Smuzhiyun SET_FIELD(task_params->sqe->contlen_cdbsize,
142*4882a593Smuzhiyun ISCSI_WQE_CDB_SIZE,
143*4882a593Smuzhiyun cmd_params->extended_cdb_sge.sge_len);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun break;
146*4882a593Smuzhiyun case ISCSI_TASK_TYPE_INITIATOR_READ:
147*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
148*4882a593Smuzhiyun ISCSI_WQE_TYPE_NORMAL);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (GET_FIELD(pdu_header->hdr_second_dword,
151*4882a593Smuzhiyun ISCSI_CMD_HDR_TOTAL_AHS_LEN))
152*4882a593Smuzhiyun SET_FIELD(task_params->sqe->contlen_cdbsize,
153*4882a593Smuzhiyun ISCSI_WQE_CDB_SIZE,
154*4882a593Smuzhiyun cmd_params->extended_cdb_sge.sge_len);
155*4882a593Smuzhiyun break;
156*4882a593Smuzhiyun case ISCSI_TASK_TYPE_LOGIN_RESPONSE:
157*4882a593Smuzhiyun case ISCSI_TASK_TYPE_MIDPATH:
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun bool advance_statsn = true;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_LOGIN_RESPONSE)
162*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
163*4882a593Smuzhiyun ISCSI_WQE_TYPE_LOGIN);
164*4882a593Smuzhiyun else
165*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_WQE_TYPE,
166*4882a593Smuzhiyun ISCSI_WQE_TYPE_MIDDLE_PATH);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_MIDPATH) {
169*4882a593Smuzhiyun u8 opcode = GET_FIELD(pdu_header->hdr_first_byte,
170*4882a593Smuzhiyun ISCSI_COMMON_HDR_OPCODE);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (opcode != ISCSI_OPCODE_TEXT_RESPONSE &&
173*4882a593Smuzhiyun (opcode != ISCSI_OPCODE_NOP_IN ||
174*4882a593Smuzhiyun pdu_header->itt == ISCSI_TTT_ALL_ONES))
175*4882a593Smuzhiyun advance_statsn = false;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_RESPONSE,
179*4882a593Smuzhiyun advance_statsn ? 1 : 0);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun if (task_params->tx_io_size) {
182*4882a593Smuzhiyun SET_FIELD(task_params->sqe->contlen_cdbsize,
183*4882a593Smuzhiyun ISCSI_WQE_CONT_LEN, task_params->tx_io_size);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (scsi_is_slow_sgl(sgl_task_params->num_sges,
186*4882a593Smuzhiyun sgl_task_params->small_mid_sge))
187*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
188*4882a593Smuzhiyun ISCSI_WQE_NUM_SGES_SLOWIO);
189*4882a593Smuzhiyun else
190*4882a593Smuzhiyun SET_FIELD(task_params->sqe->flags, ISCSI_WQE_NUM_SGES,
191*4882a593Smuzhiyun min(sgl_task_params->num_sges,
192*4882a593Smuzhiyun (u16)SCSI_NUM_SGES_SLOW_SGL_THR));
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun break;
196*4882a593Smuzhiyun default:
197*4882a593Smuzhiyun break;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
init_default_iscsi_task(struct iscsi_task_params * task_params,struct data_hdr * pdu_header,enum iscsi_task_type task_type)201*4882a593Smuzhiyun static void init_default_iscsi_task(struct iscsi_task_params *task_params,
202*4882a593Smuzhiyun struct data_hdr *pdu_header,
203*4882a593Smuzhiyun enum iscsi_task_type task_type)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun struct e4_iscsi_task_context *context;
206*4882a593Smuzhiyun u32 val;
207*4882a593Smuzhiyun u16 index;
208*4882a593Smuzhiyun u8 val_byte;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun context = task_params->context;
211*4882a593Smuzhiyun val_byte = context->mstorm_ag_context.cdu_validation;
212*4882a593Smuzhiyun memset(context, 0, sizeof(*context));
213*4882a593Smuzhiyun context->mstorm_ag_context.cdu_validation = val_byte;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun for (index = 0; index <
216*4882a593Smuzhiyun ARRAY_SIZE(context->ystorm_st_context.pdu_hdr.data.data);
217*4882a593Smuzhiyun index++) {
218*4882a593Smuzhiyun val = cpu_to_le32(pdu_header->data[index]);
219*4882a593Smuzhiyun context->ystorm_st_context.pdu_hdr.data.data[index] = val;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun context->mstorm_st_context.task_type = task_type;
223*4882a593Smuzhiyun context->mstorm_ag_context.task_cid =
224*4882a593Smuzhiyun cpu_to_le16(task_params->conn_icid);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun SET_FIELD(context->ustorm_ag_context.flags1,
227*4882a593Smuzhiyun E4_USTORM_ISCSI_TASK_AG_CTX_R2T2RECV, 1);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun context->ustorm_st_context.task_type = task_type;
230*4882a593Smuzhiyun context->ustorm_st_context.cq_rss_number = task_params->cq_rss_number;
231*4882a593Smuzhiyun context->ustorm_ag_context.icid = cpu_to_le16(task_params->conn_icid);
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun static
init_initiator_rw_cdb_ystorm_context(struct ystorm_iscsi_task_st_ctx * ystc,struct scsi_initiator_cmd_params * cmd)235*4882a593Smuzhiyun void init_initiator_rw_cdb_ystorm_context(struct ystorm_iscsi_task_st_ctx *ystc,
236*4882a593Smuzhiyun struct scsi_initiator_cmd_params *cmd)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun union iscsi_task_hdr *ctx_pdu_hdr = &ystc->pdu_hdr;
239*4882a593Smuzhiyun u32 val;
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun if (!cmd->extended_cdb_sge.sge_len)
242*4882a593Smuzhiyun return;
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun SET_FIELD(ctx_pdu_hdr->ext_cdb_cmd.hdr_second_dword,
245*4882a593Smuzhiyun ISCSI_EXT_CDB_CMD_HDR_CDB_SIZE,
246*4882a593Smuzhiyun cmd->extended_cdb_sge.sge_len);
247*4882a593Smuzhiyun val = cpu_to_le32(cmd->extended_cdb_sge.sge_addr.lo);
248*4882a593Smuzhiyun ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_addr.lo = val;
249*4882a593Smuzhiyun val = cpu_to_le32(cmd->extended_cdb_sge.sge_addr.hi);
250*4882a593Smuzhiyun ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_addr.hi = val;
251*4882a593Smuzhiyun val = cpu_to_le32(cmd->extended_cdb_sge.sge_len);
252*4882a593Smuzhiyun ctx_pdu_hdr->ext_cdb_cmd.cdb_sge.sge_len = val;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun static
init_ustorm_task_contexts(struct ustorm_iscsi_task_st_ctx * ustorm_st_cxt,struct e4_ustorm_iscsi_task_ag_ctx * ustorm_ag_cxt,u32 remaining_recv_len,u32 expected_data_transfer_len,u8 num_sges,bool tx_dif_conn_err_en)256*4882a593Smuzhiyun void init_ustorm_task_contexts(struct ustorm_iscsi_task_st_ctx *ustorm_st_cxt,
257*4882a593Smuzhiyun struct e4_ustorm_iscsi_task_ag_ctx *ustorm_ag_cxt,
258*4882a593Smuzhiyun u32 remaining_recv_len, u32 expected_data_transfer_len,
259*4882a593Smuzhiyun u8 num_sges, bool tx_dif_conn_err_en)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun u32 val;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun ustorm_st_cxt->rem_rcv_len = cpu_to_le32(remaining_recv_len);
264*4882a593Smuzhiyun ustorm_ag_cxt->exp_data_acked = cpu_to_le32(expected_data_transfer_len);
265*4882a593Smuzhiyun val = cpu_to_le32(expected_data_transfer_len);
266*4882a593Smuzhiyun ustorm_st_cxt->exp_data_transfer_len = val;
267*4882a593Smuzhiyun SET_FIELD(ustorm_st_cxt->reg1.reg1_map, ISCSI_REG1_NUM_SGES, num_sges);
268*4882a593Smuzhiyun SET_FIELD(ustorm_ag_cxt->flags2,
269*4882a593Smuzhiyun E4_USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_EN,
270*4882a593Smuzhiyun tx_dif_conn_err_en ? 1 : 0);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun static
set_rw_exp_data_acked_and_cont_len(struct e4_iscsi_task_context * context,struct iscsi_conn_params * conn_params,enum iscsi_task_type task_type,u32 task_size,u32 exp_data_transfer_len,u8 total_ahs_length)274*4882a593Smuzhiyun void set_rw_exp_data_acked_and_cont_len(struct e4_iscsi_task_context *context,
275*4882a593Smuzhiyun struct iscsi_conn_params *conn_params,
276*4882a593Smuzhiyun enum iscsi_task_type task_type,
277*4882a593Smuzhiyun u32 task_size,
278*4882a593Smuzhiyun u32 exp_data_transfer_len,
279*4882a593Smuzhiyun u8 total_ahs_length)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun u32 max_unsolicited_data = 0, val;
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun if (total_ahs_length &&
284*4882a593Smuzhiyun (task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE ||
285*4882a593Smuzhiyun task_type == ISCSI_TASK_TYPE_INITIATOR_READ))
286*4882a593Smuzhiyun SET_FIELD(context->ustorm_st_context.flags2,
287*4882a593Smuzhiyun USTORM_ISCSI_TASK_ST_CTX_AHS_EXIST, 1);
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun switch (task_type) {
290*4882a593Smuzhiyun case ISCSI_TASK_TYPE_INITIATOR_WRITE:
291*4882a593Smuzhiyun if (!conn_params->initial_r2t)
292*4882a593Smuzhiyun max_unsolicited_data = conn_params->first_burst_length;
293*4882a593Smuzhiyun else if (conn_params->immediate_data)
294*4882a593Smuzhiyun max_unsolicited_data =
295*4882a593Smuzhiyun min(conn_params->first_burst_length,
296*4882a593Smuzhiyun conn_params->max_send_pdu_length);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun context->ustorm_ag_context.exp_data_acked =
299*4882a593Smuzhiyun cpu_to_le32(total_ahs_length == 0 ?
300*4882a593Smuzhiyun min(exp_data_transfer_len,
301*4882a593Smuzhiyun max_unsolicited_data) :
302*4882a593Smuzhiyun ((u32)(total_ahs_length +
303*4882a593Smuzhiyun ISCSI_AHS_CNTL_SIZE)));
304*4882a593Smuzhiyun break;
305*4882a593Smuzhiyun case ISCSI_TASK_TYPE_TARGET_READ:
306*4882a593Smuzhiyun val = cpu_to_le32(exp_data_transfer_len);
307*4882a593Smuzhiyun context->ustorm_ag_context.exp_data_acked = val;
308*4882a593Smuzhiyun break;
309*4882a593Smuzhiyun case ISCSI_TASK_TYPE_INITIATOR_READ:
310*4882a593Smuzhiyun context->ustorm_ag_context.exp_data_acked =
311*4882a593Smuzhiyun cpu_to_le32((total_ahs_length == 0 ? 0 :
312*4882a593Smuzhiyun total_ahs_length +
313*4882a593Smuzhiyun ISCSI_AHS_CNTL_SIZE));
314*4882a593Smuzhiyun break;
315*4882a593Smuzhiyun case ISCSI_TASK_TYPE_TARGET_WRITE:
316*4882a593Smuzhiyun val = cpu_to_le32(task_size);
317*4882a593Smuzhiyun context->ustorm_ag_context.exp_cont_len = val;
318*4882a593Smuzhiyun break;
319*4882a593Smuzhiyun default:
320*4882a593Smuzhiyun break;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun static
init_rtdif_task_context(struct rdif_task_context * rdif_context,struct tdif_task_context * tdif_context,struct scsi_dif_task_params * dif_task_params,enum iscsi_task_type task_type)325*4882a593Smuzhiyun void init_rtdif_task_context(struct rdif_task_context *rdif_context,
326*4882a593Smuzhiyun struct tdif_task_context *tdif_context,
327*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params,
328*4882a593Smuzhiyun enum iscsi_task_type task_type)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun u32 val;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun if (!dif_task_params->dif_on_network || !dif_task_params->dif_on_host)
333*4882a593Smuzhiyun return;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_TARGET_WRITE ||
336*4882a593Smuzhiyun task_type == ISCSI_TASK_TYPE_INITIATOR_READ) {
337*4882a593Smuzhiyun rdif_context->app_tag_value =
338*4882a593Smuzhiyun cpu_to_le16(dif_task_params->application_tag);
339*4882a593Smuzhiyun rdif_context->partial_crc_value = cpu_to_le16(0xffff);
340*4882a593Smuzhiyun val = cpu_to_le32(dif_task_params->initial_ref_tag);
341*4882a593Smuzhiyun rdif_context->initial_ref_tag = val;
342*4882a593Smuzhiyun rdif_context->app_tag_mask =
343*4882a593Smuzhiyun cpu_to_le16(dif_task_params->application_tag_mask);
344*4882a593Smuzhiyun SET_FIELD(rdif_context->flags0, RDIF_TASK_CONTEXT_CRC_SEED,
345*4882a593Smuzhiyun dif_task_params->crc_seed ? 1 : 0);
346*4882a593Smuzhiyun SET_FIELD(rdif_context->flags0,
347*4882a593Smuzhiyun RDIF_TASK_CONTEXT_HOST_GUARD_TYPE,
348*4882a593Smuzhiyun dif_task_params->host_guard_type);
349*4882a593Smuzhiyun SET_FIELD(rdif_context->flags0,
350*4882a593Smuzhiyun RDIF_TASK_CONTEXT_PROTECTION_TYPE,
351*4882a593Smuzhiyun dif_task_params->protection_type);
352*4882a593Smuzhiyun SET_FIELD(rdif_context->flags0,
353*4882a593Smuzhiyun RDIF_TASK_CONTEXT_INITIAL_REF_TAG_VALID, 1);
354*4882a593Smuzhiyun SET_FIELD(rdif_context->flags0,
355*4882a593Smuzhiyun RDIF_TASK_CONTEXT_KEEP_REF_TAG_CONST,
356*4882a593Smuzhiyun dif_task_params->keep_ref_tag_const ? 1 : 0);
357*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
358*4882a593Smuzhiyun RDIF_TASK_CONTEXT_VALIDATE_APP_TAG,
359*4882a593Smuzhiyun (dif_task_params->validate_app_tag &&
360*4882a593Smuzhiyun dif_task_params->dif_on_network) ? 1 : 0);
361*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
362*4882a593Smuzhiyun RDIF_TASK_CONTEXT_VALIDATE_GUARD,
363*4882a593Smuzhiyun (dif_task_params->validate_guard &&
364*4882a593Smuzhiyun dif_task_params->dif_on_network) ? 1 : 0);
365*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
366*4882a593Smuzhiyun RDIF_TASK_CONTEXT_VALIDATE_REF_TAG,
367*4882a593Smuzhiyun (dif_task_params->validate_ref_tag &&
368*4882a593Smuzhiyun dif_task_params->dif_on_network) ? 1 : 0);
369*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
370*4882a593Smuzhiyun RDIF_TASK_CONTEXT_HOST_INTERFACE,
371*4882a593Smuzhiyun dif_task_params->dif_on_host ? 1 : 0);
372*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
373*4882a593Smuzhiyun RDIF_TASK_CONTEXT_NETWORK_INTERFACE,
374*4882a593Smuzhiyun dif_task_params->dif_on_network ? 1 : 0);
375*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
376*4882a593Smuzhiyun RDIF_TASK_CONTEXT_FORWARD_GUARD,
377*4882a593Smuzhiyun dif_task_params->forward_guard ? 1 : 0);
378*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
379*4882a593Smuzhiyun RDIF_TASK_CONTEXT_FORWARD_APP_TAG,
380*4882a593Smuzhiyun dif_task_params->forward_app_tag ? 1 : 0);
381*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
382*4882a593Smuzhiyun RDIF_TASK_CONTEXT_FORWARD_REF_TAG,
383*4882a593Smuzhiyun dif_task_params->forward_ref_tag ? 1 : 0);
384*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
385*4882a593Smuzhiyun RDIF_TASK_CONTEXT_FORWARD_APP_TAG_WITH_MASK,
386*4882a593Smuzhiyun dif_task_params->forward_app_tag_with_mask ? 1 : 0);
387*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
388*4882a593Smuzhiyun RDIF_TASK_CONTEXT_FORWARD_REF_TAG_WITH_MASK,
389*4882a593Smuzhiyun dif_task_params->forward_ref_tag_with_mask ? 1 : 0);
390*4882a593Smuzhiyun SET_FIELD(rdif_context->flags1,
391*4882a593Smuzhiyun RDIF_TASK_CONTEXT_INTERVAL_SIZE,
392*4882a593Smuzhiyun dif_task_params->dif_block_size_log - 9);
393*4882a593Smuzhiyun SET_FIELD(rdif_context->state,
394*4882a593Smuzhiyun RDIF_TASK_CONTEXT_REF_TAG_MASK,
395*4882a593Smuzhiyun dif_task_params->ref_tag_mask);
396*4882a593Smuzhiyun SET_FIELD(rdif_context->state, RDIF_TASK_CONTEXT_IGNORE_APP_TAG,
397*4882a593Smuzhiyun dif_task_params->ignore_app_tag);
398*4882a593Smuzhiyun }
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_TARGET_READ ||
401*4882a593Smuzhiyun task_type == ISCSI_TASK_TYPE_INITIATOR_WRITE) {
402*4882a593Smuzhiyun tdif_context->app_tag_value =
403*4882a593Smuzhiyun cpu_to_le16(dif_task_params->application_tag);
404*4882a593Smuzhiyun tdif_context->partial_crc_value_b =
405*4882a593Smuzhiyun cpu_to_le16(dif_task_params->crc_seed ? 0xffff : 0x0000);
406*4882a593Smuzhiyun tdif_context->partial_crc_value_a =
407*4882a593Smuzhiyun cpu_to_le16(dif_task_params->crc_seed ? 0xffff : 0x0000);
408*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0, TDIF_TASK_CONTEXT_CRC_SEED,
409*4882a593Smuzhiyun dif_task_params->crc_seed ? 1 : 0);
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
412*4882a593Smuzhiyun TDIF_TASK_CONTEXT_SET_ERROR_WITH_EOP,
413*4882a593Smuzhiyun dif_task_params->tx_dif_conn_err_en ? 1 : 0);
414*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1, TDIF_TASK_CONTEXT_FORWARD_GUARD,
415*4882a593Smuzhiyun dif_task_params->forward_guard ? 1 : 0);
416*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
417*4882a593Smuzhiyun TDIF_TASK_CONTEXT_FORWARD_APP_TAG,
418*4882a593Smuzhiyun dif_task_params->forward_app_tag ? 1 : 0);
419*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
420*4882a593Smuzhiyun TDIF_TASK_CONTEXT_FORWARD_REF_TAG,
421*4882a593Smuzhiyun dif_task_params->forward_ref_tag ? 1 : 0);
422*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1, TDIF_TASK_CONTEXT_INTERVAL_SIZE,
423*4882a593Smuzhiyun dif_task_params->dif_block_size_log - 9);
424*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
425*4882a593Smuzhiyun TDIF_TASK_CONTEXT_HOST_INTERFACE,
426*4882a593Smuzhiyun dif_task_params->dif_on_host ? 1 : 0);
427*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
428*4882a593Smuzhiyun TDIF_TASK_CONTEXT_NETWORK_INTERFACE,
429*4882a593Smuzhiyun dif_task_params->dif_on_network ? 1 : 0);
430*4882a593Smuzhiyun val = cpu_to_le32(dif_task_params->initial_ref_tag);
431*4882a593Smuzhiyun tdif_context->initial_ref_tag = val;
432*4882a593Smuzhiyun tdif_context->app_tag_mask =
433*4882a593Smuzhiyun cpu_to_le16(dif_task_params->application_tag_mask);
434*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
435*4882a593Smuzhiyun TDIF_TASK_CONTEXT_HOST_GUARD_TYPE,
436*4882a593Smuzhiyun dif_task_params->host_guard_type);
437*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
438*4882a593Smuzhiyun TDIF_TASK_CONTEXT_PROTECTION_TYPE,
439*4882a593Smuzhiyun dif_task_params->protection_type);
440*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
441*4882a593Smuzhiyun TDIF_TASK_CONTEXT_INITIAL_REF_TAG_VALID,
442*4882a593Smuzhiyun dif_task_params->initial_ref_tag_is_valid ? 1 : 0);
443*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
444*4882a593Smuzhiyun TDIF_TASK_CONTEXT_KEEP_REF_TAG_CONST,
445*4882a593Smuzhiyun dif_task_params->keep_ref_tag_const ? 1 : 0);
446*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
447*4882a593Smuzhiyun TDIF_TASK_CONTEXT_VALIDATE_GUARD,
448*4882a593Smuzhiyun (dif_task_params->validate_guard &&
449*4882a593Smuzhiyun dif_task_params->dif_on_host) ? 1 : 0);
450*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
451*4882a593Smuzhiyun TDIF_TASK_CONTEXT_VALIDATE_APP_TAG,
452*4882a593Smuzhiyun (dif_task_params->validate_app_tag &&
453*4882a593Smuzhiyun dif_task_params->dif_on_host) ? 1 : 0);
454*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
455*4882a593Smuzhiyun TDIF_TASK_CONTEXT_VALIDATE_REF_TAG,
456*4882a593Smuzhiyun (dif_task_params->validate_ref_tag &&
457*4882a593Smuzhiyun dif_task_params->dif_on_host) ? 1 : 0);
458*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
459*4882a593Smuzhiyun TDIF_TASK_CONTEXT_FORWARD_APP_TAG_WITH_MASK,
460*4882a593Smuzhiyun dif_task_params->forward_app_tag_with_mask ? 1 : 0);
461*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
462*4882a593Smuzhiyun TDIF_TASK_CONTEXT_FORWARD_REF_TAG_WITH_MASK,
463*4882a593Smuzhiyun dif_task_params->forward_ref_tag_with_mask ? 1 : 0);
464*4882a593Smuzhiyun SET_FIELD(tdif_context->flags1,
465*4882a593Smuzhiyun TDIF_TASK_CONTEXT_REF_TAG_MASK,
466*4882a593Smuzhiyun dif_task_params->ref_tag_mask);
467*4882a593Smuzhiyun SET_FIELD(tdif_context->flags0,
468*4882a593Smuzhiyun TDIF_TASK_CONTEXT_IGNORE_APP_TAG,
469*4882a593Smuzhiyun dif_task_params->ignore_app_tag ? 1 : 0);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun
set_local_completion_context(struct e4_iscsi_task_context * context)473*4882a593Smuzhiyun static void set_local_completion_context(struct e4_iscsi_task_context *context)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun SET_FIELD(context->ystorm_st_context.state.flags,
476*4882a593Smuzhiyun YSTORM_ISCSI_TASK_STATE_LOCAL_COMP, 1);
477*4882a593Smuzhiyun SET_FIELD(context->ustorm_st_context.flags,
478*4882a593Smuzhiyun USTORM_ISCSI_TASK_ST_CTX_LOCAL_COMP, 1);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
init_rw_iscsi_task(struct iscsi_task_params * task_params,enum iscsi_task_type task_type,struct iscsi_conn_params * conn_params,struct iscsi_common_hdr * pdu_header,struct scsi_sgl_task_params * sgl_task_params,struct scsi_initiator_cmd_params * cmd_params,struct scsi_dif_task_params * dif_task_params)481*4882a593Smuzhiyun static int init_rw_iscsi_task(struct iscsi_task_params *task_params,
482*4882a593Smuzhiyun enum iscsi_task_type task_type,
483*4882a593Smuzhiyun struct iscsi_conn_params *conn_params,
484*4882a593Smuzhiyun struct iscsi_common_hdr *pdu_header,
485*4882a593Smuzhiyun struct scsi_sgl_task_params *sgl_task_params,
486*4882a593Smuzhiyun struct scsi_initiator_cmd_params *cmd_params,
487*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun u32 exp_data_transfer_len = conn_params->max_burst_length;
490*4882a593Smuzhiyun struct e4_iscsi_task_context *cxt;
491*4882a593Smuzhiyun bool slow_io = false;
492*4882a593Smuzhiyun u32 task_size, val;
493*4882a593Smuzhiyun u8 num_sges = 0;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun task_size = calc_rw_task_size(task_params, task_type, sgl_task_params,
496*4882a593Smuzhiyun dif_task_params);
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun init_default_iscsi_task(task_params, (struct data_hdr *)pdu_header,
499*4882a593Smuzhiyun task_type);
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun cxt = task_params->context;
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun if (task_type == ISCSI_TASK_TYPE_TARGET_READ) {
505*4882a593Smuzhiyun set_local_completion_context(cxt);
506*4882a593Smuzhiyun } else if (task_type == ISCSI_TASK_TYPE_TARGET_WRITE) {
507*4882a593Smuzhiyun val = cpu_to_le32(task_size +
508*4882a593Smuzhiyun ((struct iscsi_r2t_hdr *)pdu_header)->buffer_offset);
509*4882a593Smuzhiyun cxt->ystorm_st_context.pdu_hdr.r2t.desired_data_trns_len = val;
510*4882a593Smuzhiyun cxt->mstorm_st_context.expected_itt =
511*4882a593Smuzhiyun cpu_to_le32(pdu_header->itt);
512*4882a593Smuzhiyun } else {
513*4882a593Smuzhiyun val = cpu_to_le32(task_size);
514*4882a593Smuzhiyun cxt->ystorm_st_context.pdu_hdr.cmd.expected_transfer_length =
515*4882a593Smuzhiyun val;
516*4882a593Smuzhiyun init_initiator_rw_cdb_ystorm_context(&cxt->ystorm_st_context,
517*4882a593Smuzhiyun cmd_params);
518*4882a593Smuzhiyun val = cpu_to_le32(cmd_params->sense_data_buffer_phys_addr.lo);
519*4882a593Smuzhiyun cxt->mstorm_st_context.sense_db.lo = val;
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun val = cpu_to_le32(cmd_params->sense_data_buffer_phys_addr.hi);
522*4882a593Smuzhiyun cxt->mstorm_st_context.sense_db.hi = val;
523*4882a593Smuzhiyun }
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun if (task_params->tx_io_size) {
526*4882a593Smuzhiyun init_dif_context_flags(&cxt->ystorm_st_context.state.dif_flags,
527*4882a593Smuzhiyun dif_task_params);
528*4882a593Smuzhiyun init_dif_context_flags(&cxt->ustorm_st_context.dif_flags,
529*4882a593Smuzhiyun dif_task_params);
530*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
531*4882a593Smuzhiyun &cxt->ystorm_st_context.state.data_desc,
532*4882a593Smuzhiyun sgl_task_params);
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun slow_io = scsi_is_slow_sgl(sgl_task_params->num_sges,
535*4882a593Smuzhiyun sgl_task_params->small_mid_sge);
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun num_sges = !slow_io ? min_t(u16, sgl_task_params->num_sges,
538*4882a593Smuzhiyun (u16)SCSI_NUM_SGES_SLOW_SGL_THR) :
539*4882a593Smuzhiyun ISCSI_WQE_NUM_SGES_SLOWIO;
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun if (slow_io) {
542*4882a593Smuzhiyun SET_FIELD(cxt->ystorm_st_context.state.flags,
543*4882a593Smuzhiyun YSTORM_ISCSI_TASK_STATE_SLOW_IO, 1);
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun } else if (task_params->rx_io_size) {
546*4882a593Smuzhiyun init_dif_context_flags(&cxt->mstorm_st_context.dif_flags,
547*4882a593Smuzhiyun dif_task_params);
548*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
549*4882a593Smuzhiyun &cxt->mstorm_st_context.data_desc,
550*4882a593Smuzhiyun sgl_task_params);
551*4882a593Smuzhiyun num_sges = !scsi_is_slow_sgl(sgl_task_params->num_sges,
552*4882a593Smuzhiyun sgl_task_params->small_mid_sge) ?
553*4882a593Smuzhiyun min_t(u16, sgl_task_params->num_sges,
554*4882a593Smuzhiyun (u16)SCSI_NUM_SGES_SLOW_SGL_THR) :
555*4882a593Smuzhiyun ISCSI_WQE_NUM_SGES_SLOWIO;
556*4882a593Smuzhiyun cxt->mstorm_st_context.rem_task_size = cpu_to_le32(task_size);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun
559*4882a593Smuzhiyun if (exp_data_transfer_len > task_size ||
560*4882a593Smuzhiyun task_type != ISCSI_TASK_TYPE_TARGET_WRITE)
561*4882a593Smuzhiyun exp_data_transfer_len = task_size;
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun init_ustorm_task_contexts(&task_params->context->ustorm_st_context,
564*4882a593Smuzhiyun &task_params->context->ustorm_ag_context,
565*4882a593Smuzhiyun task_size, exp_data_transfer_len, num_sges,
566*4882a593Smuzhiyun dif_task_params ?
567*4882a593Smuzhiyun dif_task_params->tx_dif_conn_err_en : false);
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun set_rw_exp_data_acked_and_cont_len(task_params->context, conn_params,
570*4882a593Smuzhiyun task_type, task_size,
571*4882a593Smuzhiyun exp_data_transfer_len,
572*4882a593Smuzhiyun GET_FIELD(pdu_header->hdr_second_dword,
573*4882a593Smuzhiyun ISCSI_CMD_HDR_TOTAL_AHS_LEN));
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun if (dif_task_params)
576*4882a593Smuzhiyun init_rtdif_task_context(&task_params->context->rdif_context,
577*4882a593Smuzhiyun &task_params->context->tdif_context,
578*4882a593Smuzhiyun dif_task_params, task_type);
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun init_sqe(task_params, sgl_task_params, dif_task_params, pdu_header,
581*4882a593Smuzhiyun cmd_params, task_type, false);
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun return 0;
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun
init_initiator_rw_iscsi_task(struct iscsi_task_params * task_params,struct iscsi_conn_params * conn_params,struct scsi_initiator_cmd_params * cmd_params,struct iscsi_cmd_hdr * cmd_header,struct scsi_sgl_task_params * tx_sgl_params,struct scsi_sgl_task_params * rx_sgl_params,struct scsi_dif_task_params * dif_task_params)586*4882a593Smuzhiyun int init_initiator_rw_iscsi_task(struct iscsi_task_params *task_params,
587*4882a593Smuzhiyun struct iscsi_conn_params *conn_params,
588*4882a593Smuzhiyun struct scsi_initiator_cmd_params *cmd_params,
589*4882a593Smuzhiyun struct iscsi_cmd_hdr *cmd_header,
590*4882a593Smuzhiyun struct scsi_sgl_task_params *tx_sgl_params,
591*4882a593Smuzhiyun struct scsi_sgl_task_params *rx_sgl_params,
592*4882a593Smuzhiyun struct scsi_dif_task_params *dif_task_params)
593*4882a593Smuzhiyun {
594*4882a593Smuzhiyun if (GET_FIELD(cmd_header->flags_attr, ISCSI_CMD_HDR_WRITE))
595*4882a593Smuzhiyun return init_rw_iscsi_task(task_params,
596*4882a593Smuzhiyun ISCSI_TASK_TYPE_INITIATOR_WRITE,
597*4882a593Smuzhiyun conn_params,
598*4882a593Smuzhiyun (struct iscsi_common_hdr *)cmd_header,
599*4882a593Smuzhiyun tx_sgl_params, cmd_params,
600*4882a593Smuzhiyun dif_task_params);
601*4882a593Smuzhiyun else if (GET_FIELD(cmd_header->flags_attr, ISCSI_CMD_HDR_READ) ||
602*4882a593Smuzhiyun (task_params->rx_io_size == 0 && task_params->tx_io_size == 0))
603*4882a593Smuzhiyun return init_rw_iscsi_task(task_params,
604*4882a593Smuzhiyun ISCSI_TASK_TYPE_INITIATOR_READ,
605*4882a593Smuzhiyun conn_params,
606*4882a593Smuzhiyun (struct iscsi_common_hdr *)cmd_header,
607*4882a593Smuzhiyun rx_sgl_params, cmd_params,
608*4882a593Smuzhiyun dif_task_params);
609*4882a593Smuzhiyun else
610*4882a593Smuzhiyun return -1;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
init_initiator_login_request_task(struct iscsi_task_params * task_params,struct iscsi_login_req_hdr * login_header,struct scsi_sgl_task_params * tx_params,struct scsi_sgl_task_params * rx_params)613*4882a593Smuzhiyun int init_initiator_login_request_task(struct iscsi_task_params *task_params,
614*4882a593Smuzhiyun struct iscsi_login_req_hdr *login_header,
615*4882a593Smuzhiyun struct scsi_sgl_task_params *tx_params,
616*4882a593Smuzhiyun struct scsi_sgl_task_params *rx_params)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun struct e4_iscsi_task_context *cxt;
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun cxt = task_params->context;
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun init_default_iscsi_task(task_params,
623*4882a593Smuzhiyun (struct data_hdr *)login_header,
624*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun init_ustorm_task_contexts(&cxt->ustorm_st_context,
627*4882a593Smuzhiyun &cxt->ustorm_ag_context,
628*4882a593Smuzhiyun task_params->rx_io_size ?
629*4882a593Smuzhiyun rx_params->total_buffer_size : 0,
630*4882a593Smuzhiyun task_params->tx_io_size ?
631*4882a593Smuzhiyun tx_params->total_buffer_size : 0, 0,
632*4882a593Smuzhiyun 0);
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun if (task_params->tx_io_size)
635*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
636*4882a593Smuzhiyun &cxt->ystorm_st_context.state.data_desc,
637*4882a593Smuzhiyun tx_params);
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun if (task_params->rx_io_size)
640*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
641*4882a593Smuzhiyun &cxt->mstorm_st_context.data_desc,
642*4882a593Smuzhiyun rx_params);
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun cxt->mstorm_st_context.rem_task_size =
645*4882a593Smuzhiyun cpu_to_le32(task_params->rx_io_size ?
646*4882a593Smuzhiyun rx_params->total_buffer_size : 0);
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun init_sqe(task_params, tx_params, NULL,
649*4882a593Smuzhiyun (struct iscsi_common_hdr *)login_header, NULL,
650*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH, false);
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun return 0;
653*4882a593Smuzhiyun }
654*4882a593Smuzhiyun
init_initiator_nop_out_task(struct iscsi_task_params * task_params,struct iscsi_nop_out_hdr * nop_out_pdu_header,struct scsi_sgl_task_params * tx_sgl_task_params,struct scsi_sgl_task_params * rx_sgl_task_params)655*4882a593Smuzhiyun int init_initiator_nop_out_task(struct iscsi_task_params *task_params,
656*4882a593Smuzhiyun struct iscsi_nop_out_hdr *nop_out_pdu_header,
657*4882a593Smuzhiyun struct scsi_sgl_task_params *tx_sgl_task_params,
658*4882a593Smuzhiyun struct scsi_sgl_task_params *rx_sgl_task_params)
659*4882a593Smuzhiyun {
660*4882a593Smuzhiyun struct e4_iscsi_task_context *cxt;
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun cxt = task_params->context;
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun init_default_iscsi_task(task_params,
665*4882a593Smuzhiyun (struct data_hdr *)nop_out_pdu_header,
666*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun if (nop_out_pdu_header->itt == ISCSI_ITT_ALL_ONES)
669*4882a593Smuzhiyun set_local_completion_context(task_params->context);
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun if (task_params->tx_io_size)
672*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
673*4882a593Smuzhiyun &cxt->ystorm_st_context.state.data_desc,
674*4882a593Smuzhiyun tx_sgl_task_params);
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun if (task_params->rx_io_size)
677*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
678*4882a593Smuzhiyun &cxt->mstorm_st_context.data_desc,
679*4882a593Smuzhiyun rx_sgl_task_params);
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun init_ustorm_task_contexts(&cxt->ustorm_st_context,
682*4882a593Smuzhiyun &cxt->ustorm_ag_context,
683*4882a593Smuzhiyun task_params->rx_io_size ?
684*4882a593Smuzhiyun rx_sgl_task_params->total_buffer_size : 0,
685*4882a593Smuzhiyun task_params->tx_io_size ?
686*4882a593Smuzhiyun tx_sgl_task_params->total_buffer_size : 0,
687*4882a593Smuzhiyun 0, 0);
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun cxt->mstorm_st_context.rem_task_size =
690*4882a593Smuzhiyun cpu_to_le32(task_params->rx_io_size ?
691*4882a593Smuzhiyun rx_sgl_task_params->total_buffer_size :
692*4882a593Smuzhiyun 0);
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun init_sqe(task_params, tx_sgl_task_params, NULL,
695*4882a593Smuzhiyun (struct iscsi_common_hdr *)nop_out_pdu_header, NULL,
696*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH, false);
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun return 0;
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun
init_initiator_logout_request_task(struct iscsi_task_params * task_params,struct iscsi_logout_req_hdr * logout_hdr,struct scsi_sgl_task_params * tx_params,struct scsi_sgl_task_params * rx_params)701*4882a593Smuzhiyun int init_initiator_logout_request_task(struct iscsi_task_params *task_params,
702*4882a593Smuzhiyun struct iscsi_logout_req_hdr *logout_hdr,
703*4882a593Smuzhiyun struct scsi_sgl_task_params *tx_params,
704*4882a593Smuzhiyun struct scsi_sgl_task_params *rx_params)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun struct e4_iscsi_task_context *cxt;
707*4882a593Smuzhiyun
708*4882a593Smuzhiyun cxt = task_params->context;
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun init_default_iscsi_task(task_params,
711*4882a593Smuzhiyun (struct data_hdr *)logout_hdr,
712*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH);
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun if (task_params->tx_io_size)
715*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
716*4882a593Smuzhiyun &cxt->ystorm_st_context.state.data_desc,
717*4882a593Smuzhiyun tx_params);
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun if (task_params->rx_io_size)
720*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
721*4882a593Smuzhiyun &cxt->mstorm_st_context.data_desc,
722*4882a593Smuzhiyun rx_params);
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun init_ustorm_task_contexts(&cxt->ustorm_st_context,
725*4882a593Smuzhiyun &cxt->ustorm_ag_context,
726*4882a593Smuzhiyun task_params->rx_io_size ?
727*4882a593Smuzhiyun rx_params->total_buffer_size : 0,
728*4882a593Smuzhiyun task_params->tx_io_size ?
729*4882a593Smuzhiyun tx_params->total_buffer_size : 0,
730*4882a593Smuzhiyun 0, 0);
731*4882a593Smuzhiyun
732*4882a593Smuzhiyun cxt->mstorm_st_context.rem_task_size =
733*4882a593Smuzhiyun cpu_to_le32(task_params->rx_io_size ?
734*4882a593Smuzhiyun rx_params->total_buffer_size : 0);
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun init_sqe(task_params, tx_params, NULL,
737*4882a593Smuzhiyun (struct iscsi_common_hdr *)logout_hdr, NULL,
738*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH, false);
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun return 0;
741*4882a593Smuzhiyun }
742*4882a593Smuzhiyun
init_initiator_tmf_request_task(struct iscsi_task_params * task_params,struct iscsi_tmf_request_hdr * tmf_header)743*4882a593Smuzhiyun int init_initiator_tmf_request_task(struct iscsi_task_params *task_params,
744*4882a593Smuzhiyun struct iscsi_tmf_request_hdr *tmf_header)
745*4882a593Smuzhiyun {
746*4882a593Smuzhiyun init_default_iscsi_task(task_params, (struct data_hdr *)tmf_header,
747*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH);
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun init_sqe(task_params, NULL, NULL,
750*4882a593Smuzhiyun (struct iscsi_common_hdr *)tmf_header, NULL,
751*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH, false);
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun return 0;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun
init_initiator_text_request_task(struct iscsi_task_params * task_params,struct iscsi_text_request_hdr * text_header,struct scsi_sgl_task_params * tx_params,struct scsi_sgl_task_params * rx_params)756*4882a593Smuzhiyun int init_initiator_text_request_task(struct iscsi_task_params *task_params,
757*4882a593Smuzhiyun struct iscsi_text_request_hdr *text_header,
758*4882a593Smuzhiyun struct scsi_sgl_task_params *tx_params,
759*4882a593Smuzhiyun struct scsi_sgl_task_params *rx_params)
760*4882a593Smuzhiyun {
761*4882a593Smuzhiyun struct e4_iscsi_task_context *cxt;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun cxt = task_params->context;
764*4882a593Smuzhiyun
765*4882a593Smuzhiyun init_default_iscsi_task(task_params,
766*4882a593Smuzhiyun (struct data_hdr *)text_header,
767*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH);
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun if (task_params->tx_io_size)
770*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->ystorm_st_context.state.sgl_params,
771*4882a593Smuzhiyun &cxt->ystorm_st_context.state.data_desc,
772*4882a593Smuzhiyun tx_params);
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun if (task_params->rx_io_size)
775*4882a593Smuzhiyun init_scsi_sgl_context(&cxt->mstorm_st_context.sgl_params,
776*4882a593Smuzhiyun &cxt->mstorm_st_context.data_desc,
777*4882a593Smuzhiyun rx_params);
778*4882a593Smuzhiyun
779*4882a593Smuzhiyun cxt->mstorm_st_context.rem_task_size =
780*4882a593Smuzhiyun cpu_to_le32(task_params->rx_io_size ?
781*4882a593Smuzhiyun rx_params->total_buffer_size : 0);
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun init_ustorm_task_contexts(&cxt->ustorm_st_context,
784*4882a593Smuzhiyun &cxt->ustorm_ag_context,
785*4882a593Smuzhiyun task_params->rx_io_size ?
786*4882a593Smuzhiyun rx_params->total_buffer_size : 0,
787*4882a593Smuzhiyun task_params->tx_io_size ?
788*4882a593Smuzhiyun tx_params->total_buffer_size : 0, 0, 0);
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun init_sqe(task_params, tx_params, NULL,
791*4882a593Smuzhiyun (struct iscsi_common_hdr *)text_header, NULL,
792*4882a593Smuzhiyun ISCSI_TASK_TYPE_MIDPATH, false);
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun return 0;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
init_cleanup_task(struct iscsi_task_params * task_params)797*4882a593Smuzhiyun int init_cleanup_task(struct iscsi_task_params *task_params)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun init_sqe(task_params, NULL, NULL, NULL, NULL, ISCSI_TASK_TYPE_MIDPATH,
800*4882a593Smuzhiyun true);
801*4882a593Smuzhiyun return 0;
802*4882a593Smuzhiyun }
803