162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
462306a36Sopenharmony_ci * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#if !defined(__EFCT_IO_H__)
862306a36Sopenharmony_ci#define __EFCT_IO_H__
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "efct_lio.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define EFCT_LOG_ENABLE_IO_ERRORS(efct)		\
1362306a36Sopenharmony_ci		(((efct) != NULL) ? (((efct)->logmask & (1U << 6)) != 0) : 0)
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define io_error_log(io, fmt, ...)  \
1662306a36Sopenharmony_ci	do { \
1762306a36Sopenharmony_ci		if (EFCT_LOG_ENABLE_IO_ERRORS(io->efct)) \
1862306a36Sopenharmony_ci			efc_log_warn(io->efct, fmt, ##__VA_ARGS__); \
1962306a36Sopenharmony_ci	} while (0)
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define SCSI_CMD_BUF_LENGTH	48
2262306a36Sopenharmony_ci#define SCSI_RSP_BUF_LENGTH	(FCP_RESP_WITH_EXT + SCSI_SENSE_BUFFERSIZE)
2362306a36Sopenharmony_ci#define EFCT_NUM_SCSI_IOS	8192
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cienum efct_io_type {
2662306a36Sopenharmony_ci	EFCT_IO_TYPE_IO = 0,
2762306a36Sopenharmony_ci	EFCT_IO_TYPE_ELS,
2862306a36Sopenharmony_ci	EFCT_IO_TYPE_CT,
2962306a36Sopenharmony_ci	EFCT_IO_TYPE_CT_RESP,
3062306a36Sopenharmony_ci	EFCT_IO_TYPE_BLS_RESP,
3162306a36Sopenharmony_ci	EFCT_IO_TYPE_ABORT,
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	EFCT_IO_TYPE_MAX,
3462306a36Sopenharmony_ci};
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_cienum efct_els_state {
3762306a36Sopenharmony_ci	EFCT_ELS_REQUEST = 0,
3862306a36Sopenharmony_ci	EFCT_ELS_REQUEST_DELAYED,
3962306a36Sopenharmony_ci	EFCT_ELS_REQUEST_DELAY_ABORT,
4062306a36Sopenharmony_ci	EFCT_ELS_REQ_ABORT,
4162306a36Sopenharmony_ci	EFCT_ELS_REQ_ABORTED,
4262306a36Sopenharmony_ci	EFCT_ELS_ABORT_IO_COMPL,
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/**
4662306a36Sopenharmony_ci * Scsi target IO object
4762306a36Sopenharmony_ci * @efct:		pointer back to efct
4862306a36Sopenharmony_ci * @instance_index:	unique instance index value
4962306a36Sopenharmony_ci * @io:			IO display name
5062306a36Sopenharmony_ci * @node:		pointer to node
5162306a36Sopenharmony_ci * @list_entry:		io list entry
5262306a36Sopenharmony_ci * @io_pending_link:	io pending list entry
5362306a36Sopenharmony_ci * @ref:		reference counter
5462306a36Sopenharmony_ci * @release:		release callback function
5562306a36Sopenharmony_ci * @init_task_tag:	initiator task tag (OX_ID) for back-end and SCSI logging
5662306a36Sopenharmony_ci * @tgt_task_tag:	target task tag (RX_ID) for back-end and SCSI logging
5762306a36Sopenharmony_ci * @hw_tag:		HW layer unique IO id
5862306a36Sopenharmony_ci * @tag:		unique IO identifier
5962306a36Sopenharmony_ci * @sgl:		SGL
6062306a36Sopenharmony_ci * @sgl_allocated:	Number of allocated SGEs
6162306a36Sopenharmony_ci * @sgl_count:		Number of SGEs in this SGL
6262306a36Sopenharmony_ci * @tgt_io:		backend target private IO data
6362306a36Sopenharmony_ci * @exp_xfer_len:	expected data transfer length, based on FC header
6462306a36Sopenharmony_ci * @hw_priv:		Declarations private to HW/SLI
6562306a36Sopenharmony_ci * @io_type:		indicates what this struct efct_io structure is used for
6662306a36Sopenharmony_ci * @hio:		hw io object
6762306a36Sopenharmony_ci * @transferred:	Number of bytes transferred
6862306a36Sopenharmony_ci * @auto_resp:		set if auto_trsp was set
6962306a36Sopenharmony_ci * @low_latency:	set if low latency request
7062306a36Sopenharmony_ci * @wq_steering:	selected WQ steering request
7162306a36Sopenharmony_ci * @wq_class:		selected WQ class if steering is class
7262306a36Sopenharmony_ci * @xfer_req:		transfer size for current request
7362306a36Sopenharmony_ci * @scsi_tgt_cb:	target callback function
7462306a36Sopenharmony_ci * @scsi_tgt_cb_arg:	target callback function argument
7562306a36Sopenharmony_ci * @abort_cb:		abort callback function
7662306a36Sopenharmony_ci * @abort_cb_arg:	abort callback function argument
7762306a36Sopenharmony_ci * @bls_cb:		BLS callback function
7862306a36Sopenharmony_ci * @bls_cb_arg:		BLS callback function argument
7962306a36Sopenharmony_ci * @tmf_cmd:		TMF command being processed
8062306a36Sopenharmony_ci * @abort_rx_id:	rx_id from the ABTS that initiated the command abort
8162306a36Sopenharmony_ci * @cmd_tgt:		True if this is a Target command
8262306a36Sopenharmony_ci * @send_abts:		when aborting, indicates ABTS is to be sent
8362306a36Sopenharmony_ci * @cmd_ini:		True if this is an Initiator command
8462306a36Sopenharmony_ci * @seq_init:		True if local node has sequence initiative
8562306a36Sopenharmony_ci * @iparam:		iparams for hw io send call
8662306a36Sopenharmony_ci * @hio_type:		HW IO type
8762306a36Sopenharmony_ci * @wire_len:		wire length
8862306a36Sopenharmony_ci * @hw_cb:		saved HW callback
8962306a36Sopenharmony_ci * @io_to_abort:	for abort handling, pointer to IO to abort
9062306a36Sopenharmony_ci * @rspbuf:		SCSI Response buffer
9162306a36Sopenharmony_ci * @timeout:		Timeout value in seconds for this IO
9262306a36Sopenharmony_ci * @cs_ctl:		CS_CTL priority for this IO
9362306a36Sopenharmony_ci * @io_free:		Is io object in freelist
9462306a36Sopenharmony_ci * @app_id:		application id
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_cistruct efct_io {
9762306a36Sopenharmony_ci	struct efct		*efct;
9862306a36Sopenharmony_ci	u32			instance_index;
9962306a36Sopenharmony_ci	const char		*display_name;
10062306a36Sopenharmony_ci	struct efct_node	*node;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	struct list_head	list_entry;
10362306a36Sopenharmony_ci	struct list_head	io_pending_link;
10462306a36Sopenharmony_ci	struct kref		ref;
10562306a36Sopenharmony_ci	void (*release)(struct kref *arg);
10662306a36Sopenharmony_ci	u32			init_task_tag;
10762306a36Sopenharmony_ci	u32			tgt_task_tag;
10862306a36Sopenharmony_ci	u32			hw_tag;
10962306a36Sopenharmony_ci	u32			tag;
11062306a36Sopenharmony_ci	struct efct_scsi_sgl	*sgl;
11162306a36Sopenharmony_ci	u32			sgl_allocated;
11262306a36Sopenharmony_ci	u32			sgl_count;
11362306a36Sopenharmony_ci	struct efct_scsi_tgt_io tgt_io;
11462306a36Sopenharmony_ci	u32			exp_xfer_len;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	void			*hw_priv;
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	enum efct_io_type	io_type;
11962306a36Sopenharmony_ci	struct efct_hw_io	*hio;
12062306a36Sopenharmony_ci	size_t			transferred;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	bool			auto_resp;
12362306a36Sopenharmony_ci	bool			low_latency;
12462306a36Sopenharmony_ci	u8			wq_steering;
12562306a36Sopenharmony_ci	u8			wq_class;
12662306a36Sopenharmony_ci	u64			xfer_req;
12762306a36Sopenharmony_ci	efct_scsi_io_cb_t	scsi_tgt_cb;
12862306a36Sopenharmony_ci	void			*scsi_tgt_cb_arg;
12962306a36Sopenharmony_ci	efct_scsi_io_cb_t	abort_cb;
13062306a36Sopenharmony_ci	void			*abort_cb_arg;
13162306a36Sopenharmony_ci	efct_scsi_io_cb_t	bls_cb;
13262306a36Sopenharmony_ci	void			*bls_cb_arg;
13362306a36Sopenharmony_ci	enum efct_scsi_tmf_cmd	tmf_cmd;
13462306a36Sopenharmony_ci	u16			abort_rx_id;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	bool			cmd_tgt;
13762306a36Sopenharmony_ci	bool			send_abts;
13862306a36Sopenharmony_ci	bool			cmd_ini;
13962306a36Sopenharmony_ci	bool			seq_init;
14062306a36Sopenharmony_ci	union efct_hw_io_param_u iparam;
14162306a36Sopenharmony_ci	enum efct_hw_io_type	hio_type;
14262306a36Sopenharmony_ci	u64			wire_len;
14362306a36Sopenharmony_ci	void			*hw_cb;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	struct efct_io		*io_to_abort;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	struct efc_dma		rspbuf;
14862306a36Sopenharmony_ci	u32			timeout;
14962306a36Sopenharmony_ci	u8			cs_ctl;
15062306a36Sopenharmony_ci	u8			io_free;
15162306a36Sopenharmony_ci	u32			app_id;
15262306a36Sopenharmony_ci};
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_cistruct efct_io_cb_arg {
15562306a36Sopenharmony_ci	int status;
15662306a36Sopenharmony_ci	int ext_status;
15762306a36Sopenharmony_ci	void *app;
15862306a36Sopenharmony_ci};
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistruct efct_io_pool *
16162306a36Sopenharmony_ciefct_io_pool_create(struct efct *efct, u32 num_sgl);
16262306a36Sopenharmony_ciint
16362306a36Sopenharmony_ciefct_io_pool_free(struct efct_io_pool *io_pool);
16462306a36Sopenharmony_ciu32
16562306a36Sopenharmony_ciefct_io_pool_allocated(struct efct_io_pool *io_pool);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistruct efct_io *
16862306a36Sopenharmony_ciefct_io_pool_io_alloc(struct efct_io_pool *io_pool);
16962306a36Sopenharmony_civoid
17062306a36Sopenharmony_ciefct_io_pool_io_free(struct efct_io_pool *io_pool, struct efct_io *io);
17162306a36Sopenharmony_cistruct efct_io *
17262306a36Sopenharmony_ciefct_io_find_tgt_io(struct efct *efct, struct efct_node *node,
17362306a36Sopenharmony_ci		    u16 ox_id, u16 rx_id);
17462306a36Sopenharmony_ci#endif /* __EFCT_IO_H__ */
175