Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2/* Copyright 2021 Marvell. All rights reserved. */
  3
  4#include <linux/kernel.h>
  5#include <linux/module.h>
  6#include <linux/pci.h>
  7#include <linux/list.h>
  8#include <linux/mm.h>
  9#include <linux/types.h>
 10#include <asm/byteorder.h>
 11#include <linux/qed/common_hsi.h>
 12#include <linux/qed/storage_common.h>
 13#include <linux/qed/nvmetcp_common.h>
 14#include <linux/qed/qed_nvmetcp_if.h>
 15#include "qed_nvmetcp_fw_funcs.h"
 16
 17#define NVMETCP_NUM_SGES_IN_CACHE 0x4
 18
 19bool nvmetcp_is_slow_sgl(u16 num_sges, bool small_mid_sge)
 20{
 21	return (num_sges > SCSI_NUM_SGES_SLOW_SGL_THR && small_mid_sge);
 22}
 23
 24void init_scsi_sgl_context(struct scsi_sgl_params *ctx_sgl_params,
 25			   struct scsi_cached_sges *ctx_data_desc,
 26			   struct storage_sgl_task_params *sgl_params)
 27{
 28	u8 num_sges_to_init = (u8)(sgl_params->num_sges > NVMETCP_NUM_SGES_IN_CACHE ?
 29				   NVMETCP_NUM_SGES_IN_CACHE : sgl_params->num_sges);
 30	u8 sge_index;
 31
 32	/* sgl params */
 33	ctx_sgl_params->sgl_addr.lo = cpu_to_le32(sgl_params->sgl_phys_addr.lo);
 34	ctx_sgl_params->sgl_addr.hi = cpu_to_le32(sgl_params->sgl_phys_addr.hi);
 35	ctx_sgl_params->sgl_total_length = cpu_to_le32(sgl_params->total_buffer_size);
 36	ctx_sgl_params->sgl_num_sges = cpu_to_le16(sgl_params->num_sges);
 37
 38	for (sge_index = 0; sge_index < num_sges_to_init; sge_index++) {
 39		ctx_data_desc->sge[sge_index].sge_addr.lo =
 40			cpu_to_le32(sgl_params->sgl[sge_index].sge_addr.lo);
 41		ctx_data_desc->sge[sge_index].sge_addr.hi =
 42			cpu_to_le32(sgl_params->sgl[sge_index].sge_addr.hi);
 43		ctx_data_desc->sge[sge_index].sge_len =
 44			cpu_to_le32(sgl_params->sgl[sge_index].sge_len);
 45	}
 46}
 47
 48static inline u32 calc_rw_task_size(struct nvmetcp_task_params *task_params,
 49				    enum nvmetcp_task_type task_type)
 50{
 51	u32 io_size;
 52
 53	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE)
 54		io_size = task_params->tx_io_size;
 55	else
 56		io_size = task_params->rx_io_size;
 57
 58	if (unlikely(!io_size))
 59		return 0;
 60
 61	return io_size;
 62}
 63
 64static inline void init_sqe(struct nvmetcp_task_params *task_params,
 65			    struct storage_sgl_task_params *sgl_task_params,
 66			    enum nvmetcp_task_type task_type)
 67{
 68	if (!task_params->sqe)
 69		return;
 70
 71	memset(task_params->sqe, 0, sizeof(*task_params->sqe));
 72	task_params->sqe->task_id = cpu_to_le16(task_params->itid);
 73
 74	switch (task_type) {
 75	case NVMETCP_TASK_TYPE_HOST_WRITE: {
 76		u32 buf_size = 0;
 77		u32 num_sges = 0;
 78
 79		SET_FIELD(task_params->sqe->contlen_cdbsize,
 80			  NVMETCP_WQE_CDB_SIZE_OR_NVMETCP_CMD, 1);
 81		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
 82			  NVMETCP_WQE_TYPE_NORMAL);
 83		if (task_params->tx_io_size) {
 84			if (task_params->send_write_incapsule)
 85				buf_size = calc_rw_task_size(task_params, task_type);
 86
 87			if (nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
 88						sgl_task_params->small_mid_sge))
 89				num_sges = NVMETCP_WQE_NUM_SGES_SLOWIO;
 90			else
 91				num_sges = min((u16)sgl_task_params->num_sges,
 92					       (u16)SCSI_NUM_SGES_SLOW_SGL_THR);
 93		}
 94		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_NUM_SGES, num_sges);
 95		SET_FIELD(task_params->sqe->contlen_cdbsize, NVMETCP_WQE_CONT_LEN, buf_size);
 96	} break;
 97
 98	case NVMETCP_TASK_TYPE_HOST_READ: {
 99		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
100			  NVMETCP_WQE_TYPE_NORMAL);
101		SET_FIELD(task_params->sqe->contlen_cdbsize,
102			  NVMETCP_WQE_CDB_SIZE_OR_NVMETCP_CMD, 1);
103	} break;
104
105	case NVMETCP_TASK_TYPE_INIT_CONN_REQUEST: {
106		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
107			  NVMETCP_WQE_TYPE_MIDDLE_PATH);
108
109		if (task_params->tx_io_size) {
110			SET_FIELD(task_params->sqe->contlen_cdbsize, NVMETCP_WQE_CONT_LEN,
111				  task_params->tx_io_size);
112			SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_NUM_SGES,
113				  min((u16)sgl_task_params->num_sges,
114				      (u16)SCSI_NUM_SGES_SLOW_SGL_THR));
115		}
116	} break;
117
118	case NVMETCP_TASK_TYPE_CLEANUP:
119		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
120			  NVMETCP_WQE_TYPE_TASK_CLEANUP);
121
122	default:
123		break;
124	}
125}
126
127/* The following function initializes of NVMeTCP task params */
128static inline void
129init_nvmetcp_task_params(struct e5_nvmetcp_task_context *context,
130			 struct nvmetcp_task_params *task_params,
131			 enum nvmetcp_task_type task_type)
132{
133	context->ystorm_st_context.state.cccid = task_params->host_cccid;
134	SET_FIELD(context->ustorm_st_context.error_flags, USTORM_NVMETCP_TASK_ST_CTX_NVME_TCP, 1);
135	context->ustorm_st_context.nvme_tcp_opaque_lo = cpu_to_le32(task_params->opq.lo);
136	context->ustorm_st_context.nvme_tcp_opaque_hi = cpu_to_le32(task_params->opq.hi);
137}
138
139/* The following function initializes default values to all tasks */
140static inline void
141init_default_nvmetcp_task(struct nvmetcp_task_params *task_params,
142			  void *pdu_header, void *nvme_cmd,
143			  enum nvmetcp_task_type task_type)
144{
145	struct e5_nvmetcp_task_context *context = task_params->context;
146	const u8 val_byte = context->mstorm_ag_context.cdu_validation;
147	u8 dw_index;
148
149	memset(context, 0, sizeof(*context));
150	init_nvmetcp_task_params(context, task_params,
151				 (enum nvmetcp_task_type)task_type);
152
153	/* Swapping requirements used below, will be removed in future FW versions */
154	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE ||
155	    task_type == NVMETCP_TASK_TYPE_HOST_READ) {
156		for (dw_index = 0;
157		     dw_index < QED_NVMETCP_CMN_HDR_SIZE / sizeof(u32);
158		     dw_index++)
159			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
160				cpu_to_le32(__swab32(((u32 *)pdu_header)[dw_index]));
161
162		for (dw_index = QED_NVMETCP_CMN_HDR_SIZE / sizeof(u32);
163		     dw_index < QED_NVMETCP_CMD_HDR_SIZE / sizeof(u32);
164		     dw_index++)
165			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
166				cpu_to_le32(__swab32(((u32 *)nvme_cmd)[dw_index - 2]));
167	} else {
168		for (dw_index = 0;
169		     dw_index < QED_NVMETCP_NON_IO_HDR_SIZE / sizeof(u32);
170		     dw_index++)
171			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
172				cpu_to_le32(__swab32(((u32 *)pdu_header)[dw_index]));
173	}
174
175	/* M-Storm Context: */
176	context->mstorm_ag_context.cdu_validation = val_byte;
177	context->mstorm_st_context.task_type = (u8)(task_type);
178	context->mstorm_ag_context.task_cid = cpu_to_le16(task_params->conn_icid);
179
180	/* Ustorm Context: */
181	SET_FIELD(context->ustorm_ag_context.flags1, E5_USTORM_NVMETCP_TASK_AG_CTX_R2T2RECV, 1);
182	context->ustorm_st_context.task_type = (u8)(task_type);
183	context->ustorm_st_context.cq_rss_number = task_params->cq_rss_number;
184	context->ustorm_ag_context.icid = cpu_to_le16(task_params->conn_icid);
185}
186
187/* The following function initializes the U-Storm Task Contexts */
188static inline void
189init_ustorm_task_contexts(struct ustorm_nvmetcp_task_st_ctx *ustorm_st_context,
190			  struct e5_ustorm_nvmetcp_task_ag_ctx *ustorm_ag_context,
191			  u32 remaining_recv_len,
192			  u32 expected_data_transfer_len, u8 num_sges,
193			  bool tx_dif_conn_err_en)
194{
195	/* Remaining data to be received in bytes. Used in validations*/
196	ustorm_st_context->rem_rcv_len = cpu_to_le32(remaining_recv_len);
197	ustorm_ag_context->exp_data_acked = cpu_to_le32(expected_data_transfer_len);
198	ustorm_st_context->exp_data_transfer_len = cpu_to_le32(expected_data_transfer_len);
199	SET_FIELD(ustorm_st_context->reg1_map, REG1_NUM_SGES, num_sges);
200	SET_FIELD(ustorm_ag_context->flags2, E5_USTORM_NVMETCP_TASK_AG_CTX_DIF_ERROR_CF_EN,
201		  tx_dif_conn_err_en ? 1 : 0);
202}
203
204/* The following function initializes Local Completion Contexts: */
205static inline void
206set_local_completion_context(struct e5_nvmetcp_task_context *context)
207{
208	SET_FIELD(context->ystorm_st_context.state.flags,
209		  YSTORM_NVMETCP_TASK_STATE_LOCAL_COMP, 1);
210	SET_FIELD(context->ustorm_st_context.flags,
211		  USTORM_NVMETCP_TASK_ST_CTX_LOCAL_COMP, 1);
212}
213
214/* Common Fastpath task init function: */
215static inline void
216init_rw_nvmetcp_task(struct nvmetcp_task_params *task_params,
217		     enum nvmetcp_task_type task_type,
218		     void *pdu_header, void *nvme_cmd,
219		     struct storage_sgl_task_params *sgl_task_params)
220{
221	struct e5_nvmetcp_task_context *context = task_params->context;
222	u32 task_size = calc_rw_task_size(task_params, task_type);
223	bool slow_io = false;
224	u8 num_sges = 0;
225
226	init_default_nvmetcp_task(task_params, pdu_header, nvme_cmd, task_type);
227
228	/* Tx/Rx: */
229	if (task_params->tx_io_size) {
230		/* if data to transmit: */
231		init_scsi_sgl_context(&context->ystorm_st_context.state.sgl_params,
232				      &context->ystorm_st_context.state.data_desc,
233				      sgl_task_params);
234		slow_io = nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
235					      sgl_task_params->small_mid_sge);
236		num_sges =
237			(u8)(!slow_io ? min((u32)sgl_task_params->num_sges,
238					    (u32)SCSI_NUM_SGES_SLOW_SGL_THR) :
239					    NVMETCP_WQE_NUM_SGES_SLOWIO);
240		if (slow_io) {
241			SET_FIELD(context->ystorm_st_context.state.flags,
242				  YSTORM_NVMETCP_TASK_STATE_SLOW_IO, 1);
243		}
244	} else if (task_params->rx_io_size) {
245		/* if data to receive: */
246		init_scsi_sgl_context(&context->mstorm_st_context.sgl_params,
247				      &context->mstorm_st_context.data_desc,
248				      sgl_task_params);
249		num_sges =
250			(u8)(!nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
251						  sgl_task_params->small_mid_sge) ?
252						  min((u32)sgl_task_params->num_sges,
253						      (u32)SCSI_NUM_SGES_SLOW_SGL_THR) :
254						      NVMETCP_WQE_NUM_SGES_SLOWIO);
255		context->mstorm_st_context.rem_task_size = cpu_to_le32(task_size);
256	}
257
258	/* Ustorm context: */
259	init_ustorm_task_contexts(&context->ustorm_st_context,
260				  &context->ustorm_ag_context,
261				  /* Remaining Receive length is the Task Size */
262				  task_size,
263				  /* The size of the transmitted task */
264				  task_size,
265				  /* num_sges */
266				  num_sges,
267				  false);
268
269	/* Set exp_data_acked */
270	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE) {
271		if (task_params->send_write_incapsule)
272			context->ustorm_ag_context.exp_data_acked = task_size;
273		else
274			context->ustorm_ag_context.exp_data_acked = 0;
275	} else if (task_type == NVMETCP_TASK_TYPE_HOST_READ) {
276		context->ustorm_ag_context.exp_data_acked = 0;
277	}
278
279	context->ustorm_ag_context.exp_cont_len = 0;
280	init_sqe(task_params, sgl_task_params, task_type);
281}
282
283static void
284init_common_initiator_read_task(struct nvmetcp_task_params *task_params,
285				struct nvme_tcp_cmd_pdu *cmd_pdu_header,
286				struct nvme_command *nvme_cmd,
287				struct storage_sgl_task_params *sgl_task_params)
288{
289	init_rw_nvmetcp_task(task_params, NVMETCP_TASK_TYPE_HOST_READ,
290			     cmd_pdu_header, nvme_cmd, sgl_task_params);
291}
292
293void init_nvmetcp_host_read_task(struct nvmetcp_task_params *task_params,
294				 struct nvme_tcp_cmd_pdu *cmd_pdu_header,
295				 struct nvme_command *nvme_cmd,
296				 struct storage_sgl_task_params *sgl_task_params)
297{
298	init_common_initiator_read_task(task_params, (void *)cmd_pdu_header,
299					(void *)nvme_cmd, sgl_task_params);
300}
301
302static void
303init_common_initiator_write_task(struct nvmetcp_task_params *task_params,
304				 struct nvme_tcp_cmd_pdu *cmd_pdu_header,
305				 struct nvme_command *nvme_cmd,
306				 struct storage_sgl_task_params *sgl_task_params)
307{
308	init_rw_nvmetcp_task(task_params, NVMETCP_TASK_TYPE_HOST_WRITE,
309			     cmd_pdu_header, nvme_cmd, sgl_task_params);
310}
311
312void init_nvmetcp_host_write_task(struct nvmetcp_task_params *task_params,
313				  struct nvme_tcp_cmd_pdu *cmd_pdu_header,
314				  struct nvme_command *nvme_cmd,
315				  struct storage_sgl_task_params *sgl_task_params)
316{
317	init_common_initiator_write_task(task_params, (void *)cmd_pdu_header,
318					 (void *)nvme_cmd, sgl_task_params);
319}
320
321static void
322init_common_login_request_task(struct nvmetcp_task_params *task_params,
323			       void *login_req_pdu_header,
324			       struct storage_sgl_task_params *tx_sgl_task_params,
325			       struct storage_sgl_task_params *rx_sgl_task_params)
326{
327	struct e5_nvmetcp_task_context *context = task_params->context;
328
329	init_default_nvmetcp_task(task_params, (void *)login_req_pdu_header, NULL,
330				  NVMETCP_TASK_TYPE_INIT_CONN_REQUEST);
331
332	/* Ustorm Context: */
333	init_ustorm_task_contexts(&context->ustorm_st_context,
334				  &context->ustorm_ag_context,
335
336				  /* Remaining Receive length is the Task Size */
337				  task_params->rx_io_size ?
338				  rx_sgl_task_params->total_buffer_size : 0,
339
340				  /* The size of the transmitted task */
341				  task_params->tx_io_size ?
342				  tx_sgl_task_params->total_buffer_size : 0,
343				  0, /* num_sges */
344				  0); /* tx_dif_conn_err_en */
345
346	/* SGL context: */
347	if (task_params->tx_io_size)
348		init_scsi_sgl_context(&context->ystorm_st_context.state.sgl_params,
349				      &context->ystorm_st_context.state.data_desc,
350				      tx_sgl_task_params);
351	if (task_params->rx_io_size)
352		init_scsi_sgl_context(&context->mstorm_st_context.sgl_params,
353				      &context->mstorm_st_context.data_desc,
354				      rx_sgl_task_params);
355
356	context->mstorm_st_context.rem_task_size =
357		cpu_to_le32(task_params->rx_io_size ?
358				 rx_sgl_task_params->total_buffer_size : 0);
359	init_sqe(task_params, tx_sgl_task_params, NVMETCP_TASK_TYPE_INIT_CONN_REQUEST);
360}
361
362/* The following function initializes Login task in Host mode: */
363void init_nvmetcp_init_conn_req_task(struct nvmetcp_task_params *task_params,
364				     struct nvme_tcp_icreq_pdu *init_conn_req_pdu_hdr,
365				     struct storage_sgl_task_params *tx_sgl_task_params,
366				     struct storage_sgl_task_params *rx_sgl_task_params)
367{
368	init_common_login_request_task(task_params, init_conn_req_pdu_hdr,
369				       tx_sgl_task_params, rx_sgl_task_params);
370}
371
372void init_cleanup_task_nvmetcp(struct nvmetcp_task_params *task_params)
373{
374	init_sqe(task_params, NULL, NVMETCP_TASK_TYPE_CLEANUP);
375}
v6.2
  1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
  2/* Copyright 2021 Marvell. All rights reserved. */
  3
  4#include <linux/kernel.h>
  5#include <linux/module.h>
  6#include <linux/pci.h>
  7#include <linux/list.h>
  8#include <linux/mm.h>
  9#include <linux/types.h>
 10#include <asm/byteorder.h>
 11#include <linux/qed/common_hsi.h>
 12#include <linux/qed/storage_common.h>
 13#include <linux/qed/nvmetcp_common.h>
 14#include <linux/qed/qed_nvmetcp_if.h>
 15#include "qed_nvmetcp_fw_funcs.h"
 16
 17#define NVMETCP_NUM_SGES_IN_CACHE 0x4
 18
 19bool nvmetcp_is_slow_sgl(u16 num_sges, bool small_mid_sge)
 20{
 21	return (num_sges > SCSI_NUM_SGES_SLOW_SGL_THR && small_mid_sge);
 22}
 23
 24void init_scsi_sgl_context(struct scsi_sgl_params *ctx_sgl_params,
 25			   struct scsi_cached_sges *ctx_data_desc,
 26			   struct storage_sgl_task_params *sgl_params)
 27{
 28	u8 num_sges_to_init = (u8)(sgl_params->num_sges > NVMETCP_NUM_SGES_IN_CACHE ?
 29				   NVMETCP_NUM_SGES_IN_CACHE : sgl_params->num_sges);
 30	u8 sge_index;
 31
 32	/* sgl params */
 33	ctx_sgl_params->sgl_addr.lo = cpu_to_le32(sgl_params->sgl_phys_addr.lo);
 34	ctx_sgl_params->sgl_addr.hi = cpu_to_le32(sgl_params->sgl_phys_addr.hi);
 35	ctx_sgl_params->sgl_total_length = cpu_to_le32(sgl_params->total_buffer_size);
 36	ctx_sgl_params->sgl_num_sges = cpu_to_le16(sgl_params->num_sges);
 37
 38	for (sge_index = 0; sge_index < num_sges_to_init; sge_index++) {
 39		ctx_data_desc->sge[sge_index].sge_addr.lo =
 40			cpu_to_le32(sgl_params->sgl[sge_index].sge_addr.lo);
 41		ctx_data_desc->sge[sge_index].sge_addr.hi =
 42			cpu_to_le32(sgl_params->sgl[sge_index].sge_addr.hi);
 43		ctx_data_desc->sge[sge_index].sge_len =
 44			cpu_to_le32(sgl_params->sgl[sge_index].sge_len);
 45	}
 46}
 47
 48static inline u32 calc_rw_task_size(struct nvmetcp_task_params *task_params,
 49				    enum nvmetcp_task_type task_type)
 50{
 51	u32 io_size;
 52
 53	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE)
 54		io_size = task_params->tx_io_size;
 55	else
 56		io_size = task_params->rx_io_size;
 57
 58	if (unlikely(!io_size))
 59		return 0;
 60
 61	return io_size;
 62}
 63
 64static inline void init_sqe(struct nvmetcp_task_params *task_params,
 65			    struct storage_sgl_task_params *sgl_task_params,
 66			    enum nvmetcp_task_type task_type)
 67{
 68	if (!task_params->sqe)
 69		return;
 70
 71	memset(task_params->sqe, 0, sizeof(*task_params->sqe));
 72	task_params->sqe->task_id = cpu_to_le16(task_params->itid);
 73
 74	switch (task_type) {
 75	case NVMETCP_TASK_TYPE_HOST_WRITE: {
 76		u32 buf_size = 0;
 77		u32 num_sges = 0;
 78
 79		SET_FIELD(task_params->sqe->contlen_cdbsize,
 80			  NVMETCP_WQE_CDB_SIZE_OR_NVMETCP_CMD, 1);
 81		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
 82			  NVMETCP_WQE_TYPE_NORMAL);
 83		if (task_params->tx_io_size) {
 84			if (task_params->send_write_incapsule)
 85				buf_size = calc_rw_task_size(task_params, task_type);
 86
 87			if (nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
 88						sgl_task_params->small_mid_sge))
 89				num_sges = NVMETCP_WQE_NUM_SGES_SLOWIO;
 90			else
 91				num_sges = min((u16)sgl_task_params->num_sges,
 92					       (u16)SCSI_NUM_SGES_SLOW_SGL_THR);
 93		}
 94		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_NUM_SGES, num_sges);
 95		SET_FIELD(task_params->sqe->contlen_cdbsize, NVMETCP_WQE_CONT_LEN, buf_size);
 96	} break;
 97
 98	case NVMETCP_TASK_TYPE_HOST_READ: {
 99		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
100			  NVMETCP_WQE_TYPE_NORMAL);
101		SET_FIELD(task_params->sqe->contlen_cdbsize,
102			  NVMETCP_WQE_CDB_SIZE_OR_NVMETCP_CMD, 1);
103	} break;
104
105	case NVMETCP_TASK_TYPE_INIT_CONN_REQUEST: {
106		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
107			  NVMETCP_WQE_TYPE_MIDDLE_PATH);
108
109		if (task_params->tx_io_size) {
110			SET_FIELD(task_params->sqe->contlen_cdbsize, NVMETCP_WQE_CONT_LEN,
111				  task_params->tx_io_size);
112			SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_NUM_SGES,
113				  min((u16)sgl_task_params->num_sges,
114				      (u16)SCSI_NUM_SGES_SLOW_SGL_THR));
115		}
116	} break;
117
118	case NVMETCP_TASK_TYPE_CLEANUP:
119		SET_FIELD(task_params->sqe->flags, NVMETCP_WQE_WQE_TYPE,
120			  NVMETCP_WQE_TYPE_TASK_CLEANUP);
121
122	default:
123		break;
124	}
125}
126
127/* The following function initializes of NVMeTCP task params */
128static inline void
129init_nvmetcp_task_params(struct e5_nvmetcp_task_context *context,
130			 struct nvmetcp_task_params *task_params,
131			 enum nvmetcp_task_type task_type)
132{
133	context->ystorm_st_context.state.cccid = task_params->host_cccid;
134	SET_FIELD(context->ustorm_st_context.error_flags, USTORM_NVMETCP_TASK_ST_CTX_NVME_TCP, 1);
135	context->ustorm_st_context.nvme_tcp_opaque_lo = cpu_to_le32(task_params->opq.lo);
136	context->ustorm_st_context.nvme_tcp_opaque_hi = cpu_to_le32(task_params->opq.hi);
137}
138
139/* The following function initializes default values to all tasks */
140static inline void
141init_default_nvmetcp_task(struct nvmetcp_task_params *task_params,
142			  void *pdu_header, void *nvme_cmd,
143			  enum nvmetcp_task_type task_type)
144{
145	struct e5_nvmetcp_task_context *context = task_params->context;
146	const u8 val_byte = context->mstorm_ag_context.cdu_validation;
147	u8 dw_index;
148
149	memset(context, 0, sizeof(*context));
150	init_nvmetcp_task_params(context, task_params,
151				 (enum nvmetcp_task_type)task_type);
152
153	/* Swapping requirements used below, will be removed in future FW versions */
154	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE ||
155	    task_type == NVMETCP_TASK_TYPE_HOST_READ) {
156		for (dw_index = 0;
157		     dw_index < QED_NVMETCP_CMN_HDR_SIZE / sizeof(u32);
158		     dw_index++)
159			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
160				cpu_to_le32(__swab32(((u32 *)pdu_header)[dw_index]));
161
162		for (dw_index = QED_NVMETCP_CMN_HDR_SIZE / sizeof(u32);
163		     dw_index < QED_NVMETCP_CMD_HDR_SIZE / sizeof(u32);
164		     dw_index++)
165			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
166				cpu_to_le32(__swab32(((u32 *)nvme_cmd)[dw_index - 2]));
167	} else {
168		for (dw_index = 0;
169		     dw_index < QED_NVMETCP_NON_IO_HDR_SIZE / sizeof(u32);
170		     dw_index++)
171			context->ystorm_st_context.pdu_hdr.task_hdr.reg[dw_index] =
172				cpu_to_le32(__swab32(((u32 *)pdu_header)[dw_index]));
173	}
174
175	/* M-Storm Context: */
176	context->mstorm_ag_context.cdu_validation = val_byte;
177	context->mstorm_st_context.task_type = (u8)(task_type);
178	context->mstorm_ag_context.task_cid = cpu_to_le16(task_params->conn_icid);
179
180	/* Ustorm Context: */
181	SET_FIELD(context->ustorm_ag_context.flags1, E5_USTORM_NVMETCP_TASK_AG_CTX_R2T2RECV, 1);
182	context->ustorm_st_context.task_type = (u8)(task_type);
183	context->ustorm_st_context.cq_rss_number = task_params->cq_rss_number;
184	context->ustorm_ag_context.icid = cpu_to_le16(task_params->conn_icid);
185}
186
187/* The following function initializes the U-Storm Task Contexts */
188static inline void
189init_ustorm_task_contexts(struct ustorm_nvmetcp_task_st_ctx *ustorm_st_context,
190			  struct e5_ustorm_nvmetcp_task_ag_ctx *ustorm_ag_context,
191			  u32 remaining_recv_len,
192			  u32 expected_data_transfer_len, u8 num_sges,
193			  bool tx_dif_conn_err_en)
194{
195	/* Remaining data to be received in bytes. Used in validations*/
196	ustorm_st_context->rem_rcv_len = cpu_to_le32(remaining_recv_len);
197	ustorm_ag_context->exp_data_acked = cpu_to_le32(expected_data_transfer_len);
198	ustorm_st_context->exp_data_transfer_len = cpu_to_le32(expected_data_transfer_len);
199	SET_FIELD(ustorm_st_context->reg1_map, REG1_NUM_SGES, num_sges);
200	SET_FIELD(ustorm_ag_context->flags2, E5_USTORM_NVMETCP_TASK_AG_CTX_DIF_ERROR_CF_EN,
201		  tx_dif_conn_err_en ? 1 : 0);
202}
203
204/* The following function initializes Local Completion Contexts: */
205static inline void
206set_local_completion_context(struct e5_nvmetcp_task_context *context)
207{
208	SET_FIELD(context->ystorm_st_context.state.flags,
209		  YSTORM_NVMETCP_TASK_STATE_LOCAL_COMP, 1);
210	SET_FIELD(context->ustorm_st_context.flags,
211		  USTORM_NVMETCP_TASK_ST_CTX_LOCAL_COMP, 1);
212}
213
214/* Common Fastpath task init function: */
215static inline void
216init_rw_nvmetcp_task(struct nvmetcp_task_params *task_params,
217		     enum nvmetcp_task_type task_type,
218		     void *pdu_header, void *nvme_cmd,
219		     struct storage_sgl_task_params *sgl_task_params)
220{
221	struct e5_nvmetcp_task_context *context = task_params->context;
222	u32 task_size = calc_rw_task_size(task_params, task_type);
223	bool slow_io = false;
224	u8 num_sges = 0;
225
226	init_default_nvmetcp_task(task_params, pdu_header, nvme_cmd, task_type);
227
228	/* Tx/Rx: */
229	if (task_params->tx_io_size) {
230		/* if data to transmit: */
231		init_scsi_sgl_context(&context->ystorm_st_context.state.sgl_params,
232				      &context->ystorm_st_context.state.data_desc,
233				      sgl_task_params);
234		slow_io = nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
235					      sgl_task_params->small_mid_sge);
236		num_sges =
237			(u8)(!slow_io ? min((u32)sgl_task_params->num_sges,
238					    (u32)SCSI_NUM_SGES_SLOW_SGL_THR) :
239					    NVMETCP_WQE_NUM_SGES_SLOWIO);
240		if (slow_io) {
241			SET_FIELD(context->ystorm_st_context.state.flags,
242				  YSTORM_NVMETCP_TASK_STATE_SLOW_IO, 1);
243		}
244	} else if (task_params->rx_io_size) {
245		/* if data to receive: */
246		init_scsi_sgl_context(&context->mstorm_st_context.sgl_params,
247				      &context->mstorm_st_context.data_desc,
248				      sgl_task_params);
249		num_sges =
250			(u8)(!nvmetcp_is_slow_sgl(sgl_task_params->num_sges,
251						  sgl_task_params->small_mid_sge) ?
252						  min((u32)sgl_task_params->num_sges,
253						      (u32)SCSI_NUM_SGES_SLOW_SGL_THR) :
254						      NVMETCP_WQE_NUM_SGES_SLOWIO);
255		context->mstorm_st_context.rem_task_size = cpu_to_le32(task_size);
256	}
257
258	/* Ustorm context: */
259	init_ustorm_task_contexts(&context->ustorm_st_context,
260				  &context->ustorm_ag_context,
261				  /* Remaining Receive length is the Task Size */
262				  task_size,
263				  /* The size of the transmitted task */
264				  task_size,
265				  /* num_sges */
266				  num_sges,
267				  false);
268
269	/* Set exp_data_acked */
270	if (task_type == NVMETCP_TASK_TYPE_HOST_WRITE) {
271		if (task_params->send_write_incapsule)
272			context->ustorm_ag_context.exp_data_acked = task_size;
273		else
274			context->ustorm_ag_context.exp_data_acked = 0;
275	} else if (task_type == NVMETCP_TASK_TYPE_HOST_READ) {
276		context->ustorm_ag_context.exp_data_acked = 0;
277	}
278
279	context->ustorm_ag_context.exp_cont_len = 0;
280	init_sqe(task_params, sgl_task_params, task_type);
281}
282
283static void
284init_common_initiator_read_task(struct nvmetcp_task_params *task_params,
285				struct nvme_tcp_cmd_pdu *cmd_pdu_header,
286				struct nvme_command *nvme_cmd,
287				struct storage_sgl_task_params *sgl_task_params)
288{
289	init_rw_nvmetcp_task(task_params, NVMETCP_TASK_TYPE_HOST_READ,
290			     cmd_pdu_header, nvme_cmd, sgl_task_params);
291}
292
293void init_nvmetcp_host_read_task(struct nvmetcp_task_params *task_params,
294				 struct nvme_tcp_cmd_pdu *cmd_pdu_header,
295				 struct nvme_command *nvme_cmd,
296				 struct storage_sgl_task_params *sgl_task_params)
297{
298	init_common_initiator_read_task(task_params, (void *)cmd_pdu_header,
299					(void *)nvme_cmd, sgl_task_params);
300}
301
302static void
303init_common_initiator_write_task(struct nvmetcp_task_params *task_params,
304				 struct nvme_tcp_cmd_pdu *cmd_pdu_header,
305				 struct nvme_command *nvme_cmd,
306				 struct storage_sgl_task_params *sgl_task_params)
307{
308	init_rw_nvmetcp_task(task_params, NVMETCP_TASK_TYPE_HOST_WRITE,
309			     cmd_pdu_header, nvme_cmd, sgl_task_params);
310}
311
312void init_nvmetcp_host_write_task(struct nvmetcp_task_params *task_params,
313				  struct nvme_tcp_cmd_pdu *cmd_pdu_header,
314				  struct nvme_command *nvme_cmd,
315				  struct storage_sgl_task_params *sgl_task_params)
316{
317	init_common_initiator_write_task(task_params, (void *)cmd_pdu_header,
318					 (void *)nvme_cmd, sgl_task_params);
319}
320
321static void
322init_common_login_request_task(struct nvmetcp_task_params *task_params,
323			       void *login_req_pdu_header,
324			       struct storage_sgl_task_params *tx_sgl_task_params,
325			       struct storage_sgl_task_params *rx_sgl_task_params)
326{
327	struct e5_nvmetcp_task_context *context = task_params->context;
328
329	init_default_nvmetcp_task(task_params, (void *)login_req_pdu_header, NULL,
330				  NVMETCP_TASK_TYPE_INIT_CONN_REQUEST);
331
332	/* Ustorm Context: */
333	init_ustorm_task_contexts(&context->ustorm_st_context,
334				  &context->ustorm_ag_context,
335
336				  /* Remaining Receive length is the Task Size */
337				  task_params->rx_io_size ?
338				  rx_sgl_task_params->total_buffer_size : 0,
339
340				  /* The size of the transmitted task */
341				  task_params->tx_io_size ?
342				  tx_sgl_task_params->total_buffer_size : 0,
343				  0, /* num_sges */
344				  0); /* tx_dif_conn_err_en */
345
346	/* SGL context: */
347	if (task_params->tx_io_size)
348		init_scsi_sgl_context(&context->ystorm_st_context.state.sgl_params,
349				      &context->ystorm_st_context.state.data_desc,
350				      tx_sgl_task_params);
351	if (task_params->rx_io_size)
352		init_scsi_sgl_context(&context->mstorm_st_context.sgl_params,
353				      &context->mstorm_st_context.data_desc,
354				      rx_sgl_task_params);
355
356	context->mstorm_st_context.rem_task_size =
357		cpu_to_le32(task_params->rx_io_size ?
358				 rx_sgl_task_params->total_buffer_size : 0);
359	init_sqe(task_params, tx_sgl_task_params, NVMETCP_TASK_TYPE_INIT_CONN_REQUEST);
360}
361
362/* The following function initializes Login task in Host mode: */
363void init_nvmetcp_init_conn_req_task(struct nvmetcp_task_params *task_params,
364				     struct nvme_tcp_icreq_pdu *init_conn_req_pdu_hdr,
365				     struct storage_sgl_task_params *tx_sgl_task_params,
366				     struct storage_sgl_task_params *rx_sgl_task_params)
367{
368	init_common_login_request_task(task_params, init_conn_req_pdu_hdr,
369				       tx_sgl_task_params, rx_sgl_task_params);
370}
371
372void init_cleanup_task_nvmetcp(struct nvmetcp_task_params *task_params)
373{
374	init_sqe(task_params, NULL, NVMETCP_TASK_TYPE_CLEANUP);
375}