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#ifndef __EFCT_LIO_H__
862306a36Sopenharmony_ci#define __EFCT_LIO_H__
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "efct_scsi.h"
1162306a36Sopenharmony_ci#include <target/target_core_base.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define efct_lio_io_printf(io, fmt, ...)			\
1462306a36Sopenharmony_ci	efc_log_debug(io->efct,					\
1562306a36Sopenharmony_ci		"[%s] [%04x][i:%04x t:%04x h:%04x]" fmt,\
1662306a36Sopenharmony_ci		io->node->display_name, io->instance_index,	\
1762306a36Sopenharmony_ci		io->init_task_tag, io->tgt_task_tag, io->hw_tag,\
1862306a36Sopenharmony_ci		##__VA_ARGS__)
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define efct_lio_tmfio_printf(io, fmt, ...)			\
2162306a36Sopenharmony_ci	efc_log_debug(io->efct,					\
2262306a36Sopenharmony_ci		"[%s] [%04x][i:%04x t:%04x h:%04x][f:%02x]" fmt,\
2362306a36Sopenharmony_ci		io->node->display_name, io->instance_index,	\
2462306a36Sopenharmony_ci		io->init_task_tag, io->tgt_task_tag, io->hw_tag,\
2562306a36Sopenharmony_ci		io->tgt_io.tmf,  ##__VA_ARGS__)
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define efct_set_lio_io_state(io, value) (io->tgt_io.state |= value)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistruct efct_lio_wq_data {
3062306a36Sopenharmony_ci	struct efct		*efct;
3162306a36Sopenharmony_ci	void			*ptr;
3262306a36Sopenharmony_ci	struct work_struct	work;
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* Target private efct structure */
3662306a36Sopenharmony_cistruct efct_scsi_tgt {
3762306a36Sopenharmony_ci	u32			max_sge;
3862306a36Sopenharmony_ci	u32			max_sgl;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	/*
4162306a36Sopenharmony_ci	 * Variables used to send task set full. We are using a high watermark
4262306a36Sopenharmony_ci	 * method to send task set full. We will reserve a fixed number of IOs
4362306a36Sopenharmony_ci	 * per initiator plus a fudge factor. Once we reach this number,
4462306a36Sopenharmony_ci	 * then the target will start sending task set full/busy responses.
4562306a36Sopenharmony_ci	 */
4662306a36Sopenharmony_ci	atomic_t		initiator_count;
4762306a36Sopenharmony_ci	atomic_t		ios_in_use;
4862306a36Sopenharmony_ci	atomic_t		io_high_watermark;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	atomic_t		watermark_hit;
5162306a36Sopenharmony_ci	int			watermark_min;
5262306a36Sopenharmony_ci	int			watermark_max;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	struct efct_lio_nport	*lio_nport;
5562306a36Sopenharmony_ci	struct efct_lio_tpg	*tpg;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	struct list_head	vport_list;
5862306a36Sopenharmony_ci	/* Protects vport list*/
5962306a36Sopenharmony_ci	spinlock_t		efct_lio_lock;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	u64			wwnn;
6262306a36Sopenharmony_ci};
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistruct efct_scsi_tgt_nport {
6562306a36Sopenharmony_ci	struct efct_lio_nport	*lio_nport;
6662306a36Sopenharmony_ci};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistruct efct_node {
6962306a36Sopenharmony_ci	struct list_head	list_entry;
7062306a36Sopenharmony_ci	struct kref		ref;
7162306a36Sopenharmony_ci	void			(*release)(struct kref *arg);
7262306a36Sopenharmony_ci	struct efct		*efct;
7362306a36Sopenharmony_ci	struct efc_node		*node;
7462306a36Sopenharmony_ci	struct se_session	*session;
7562306a36Sopenharmony_ci	spinlock_t		active_ios_lock;
7662306a36Sopenharmony_ci	struct list_head	active_ios;
7762306a36Sopenharmony_ci	char			display_name[EFC_NAME_LENGTH];
7862306a36Sopenharmony_ci	u32			port_fc_id;
7962306a36Sopenharmony_ci	u32			node_fc_id;
8062306a36Sopenharmony_ci	u32			vpi;
8162306a36Sopenharmony_ci	u32			rpi;
8262306a36Sopenharmony_ci	u32			abort_cnt;
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_RECV_CMD		(1 << 0)
8662306a36Sopenharmony_ci#define EFCT_LIO_STATE_TGT_SUBMIT_CMD		(1 << 1)
8762306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_QUEUE_DATA_IN	(1 << 2)
8862306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_WRITE_PENDING	(1 << 3)
8962306a36Sopenharmony_ci#define EFCT_LIO_STATE_TGT_EXECUTE_CMD		(1 << 4)
9062306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_SEND_RD_DATA	(1 << 5)
9162306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_CHK_STOP_FREE	(1 << 6)
9262306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_DATA_DONE		(1 << 7)
9362306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_QUEUE_STATUS		(1 << 8)
9462306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_SEND_RSP		(1 << 9)
9562306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_RSP_DONE		(1 << 10)
9662306a36Sopenharmony_ci#define EFCT_LIO_STATE_TGT_GENERIC_FREE		(1 << 11)
9762306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_RECV_TMF		(1 << 12)
9862306a36Sopenharmony_ci#define EFCT_LIO_STATE_TGT_SUBMIT_TMR		(1 << 13)
9962306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_WRITE_PEND_STATUS	(1 << 14)
10062306a36Sopenharmony_ci#define EFCT_LIO_STATE_TGT_GENERIC_REQ_FAILURE  (1 << 15)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_ABORTED_TASK		(1 << 29)
10362306a36Sopenharmony_ci#define EFCT_LIO_STATE_TFO_RELEASE_CMD		(1 << 30)
10462306a36Sopenharmony_ci#define EFCT_LIO_STATE_SCSI_CMPL_CMD		(1u << 31)
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistruct efct_scsi_tgt_io {
10762306a36Sopenharmony_ci	struct se_cmd		cmd;
10862306a36Sopenharmony_ci	unsigned char		sense_buffer[TRANSPORT_SENSE_BUFFER];
10962306a36Sopenharmony_ci	enum dma_data_direction	ddir;
11062306a36Sopenharmony_ci	int			task_attr;
11162306a36Sopenharmony_ci	u64			lun;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	u32			state;
11462306a36Sopenharmony_ci	u8			tmf;
11562306a36Sopenharmony_ci	struct efct_io		*io_to_abort;
11662306a36Sopenharmony_ci	u32			seg_map_cnt;
11762306a36Sopenharmony_ci	u32			seg_cnt;
11862306a36Sopenharmony_ci	u32			cur_seg;
11962306a36Sopenharmony_ci	enum efct_scsi_io_status err;
12062306a36Sopenharmony_ci	bool			aborting;
12162306a36Sopenharmony_ci	bool			rsp_sent;
12262306a36Sopenharmony_ci	u32			transferred_len;
12362306a36Sopenharmony_ci};
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/* Handler return codes */
12662306a36Sopenharmony_cienum {
12762306a36Sopenharmony_ci	SCSI_HANDLER_DATAPHASE_STARTED = 1,
12862306a36Sopenharmony_ci	SCSI_HANDLER_RESP_STARTED,
12962306a36Sopenharmony_ci	SCSI_HANDLER_VALIDATED_DATAPHASE_STARTED,
13062306a36Sopenharmony_ci	SCSI_CMD_NOT_SUPPORTED,
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#define WWN_NAME_LEN		32
13462306a36Sopenharmony_cistruct efct_lio_vport {
13562306a36Sopenharmony_ci	u64			wwpn;
13662306a36Sopenharmony_ci	u64			npiv_wwpn;
13762306a36Sopenharmony_ci	u64			npiv_wwnn;
13862306a36Sopenharmony_ci	unsigned char		wwpn_str[WWN_NAME_LEN];
13962306a36Sopenharmony_ci	struct se_wwn		vport_wwn;
14062306a36Sopenharmony_ci	struct efct_lio_tpg	*tpg;
14162306a36Sopenharmony_ci	struct efct		*efct;
14262306a36Sopenharmony_ci	struct Scsi_Host	*shost;
14362306a36Sopenharmony_ci	struct fc_vport		*fc_vport;
14462306a36Sopenharmony_ci	atomic_t		enable;
14562306a36Sopenharmony_ci};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistruct efct_lio_nport {
14862306a36Sopenharmony_ci	u64			wwpn;
14962306a36Sopenharmony_ci	unsigned char		wwpn_str[WWN_NAME_LEN];
15062306a36Sopenharmony_ci	struct se_wwn		nport_wwn;
15162306a36Sopenharmony_ci	struct efct_lio_tpg	*tpg;
15262306a36Sopenharmony_ci	struct efct		*efct;
15362306a36Sopenharmony_ci	atomic_t		enable;
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistruct efct_lio_tpg_attrib {
15762306a36Sopenharmony_ci	u32			generate_node_acls;
15862306a36Sopenharmony_ci	u32			cache_dynamic_acls;
15962306a36Sopenharmony_ci	u32			demo_mode_write_protect;
16062306a36Sopenharmony_ci	u32			prod_mode_write_protect;
16162306a36Sopenharmony_ci	u32			demo_mode_login_only;
16262306a36Sopenharmony_ci	bool			session_deletion_wait;
16362306a36Sopenharmony_ci};
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistruct efct_lio_tpg {
16662306a36Sopenharmony_ci	struct se_portal_group	tpg;
16762306a36Sopenharmony_ci	struct efct_lio_nport	*nport;
16862306a36Sopenharmony_ci	struct efct_lio_vport	*vport;
16962306a36Sopenharmony_ci	struct efct_lio_tpg_attrib tpg_attrib;
17062306a36Sopenharmony_ci	unsigned short		tpgt;
17162306a36Sopenharmony_ci	bool			enabled;
17262306a36Sopenharmony_ci};
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_cistruct efct_lio_nacl {
17562306a36Sopenharmony_ci	u64			nport_wwnn;
17662306a36Sopenharmony_ci	char			nport_name[WWN_NAME_LEN];
17762306a36Sopenharmony_ci	struct se_session	*session;
17862306a36Sopenharmony_ci	struct se_node_acl	se_node_acl;
17962306a36Sopenharmony_ci};
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistruct efct_lio_vport_list_t {
18262306a36Sopenharmony_ci	struct list_head	list_entry;
18362306a36Sopenharmony_ci	struct efct_lio_vport	*lio_vport;
18462306a36Sopenharmony_ci};
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciint efct_scsi_tgt_driver_init(void);
18762306a36Sopenharmony_ciint efct_scsi_tgt_driver_exit(void);
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci#endif /*__EFCT_LIO_H__ */
190