xref: /openbmc/linux/drivers/scsi/elx/efct/efct_scsi.h (revision 3e641400)
1*3e641400SJames Smart /* SPDX-License-Identifier: GPL-2.0 */
2*3e641400SJames Smart /*
3*3e641400SJames Smart  * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
4*3e641400SJames Smart  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
5*3e641400SJames Smart  */
6*3e641400SJames Smart 
7*3e641400SJames Smart #if !defined(__EFCT_SCSI_H__)
8*3e641400SJames Smart #define __EFCT_SCSI_H__
9*3e641400SJames Smart #include <scsi/scsi_host.h>
10*3e641400SJames Smart #include <scsi/scsi_transport_fc.h>
11*3e641400SJames Smart 
12*3e641400SJames Smart /* efct_scsi_rcv_cmd() efct_scsi_rcv_tmf() flags */
13*3e641400SJames Smart #define EFCT_SCSI_CMD_DIR_IN		(1 << 0)
14*3e641400SJames Smart #define EFCT_SCSI_CMD_DIR_OUT		(1 << 1)
15*3e641400SJames Smart #define EFCT_SCSI_CMD_SIMPLE		(1 << 2)
16*3e641400SJames Smart #define EFCT_SCSI_CMD_HEAD_OF_QUEUE	(1 << 3)
17*3e641400SJames Smart #define EFCT_SCSI_CMD_ORDERED		(1 << 4)
18*3e641400SJames Smart #define EFCT_SCSI_CMD_UNTAGGED		(1 << 5)
19*3e641400SJames Smart #define EFCT_SCSI_CMD_ACA		(1 << 6)
20*3e641400SJames Smart #define EFCT_SCSI_FIRST_BURST_ERR	(1 << 7)
21*3e641400SJames Smart #define EFCT_SCSI_FIRST_BURST_ABORTED	(1 << 8)
22*3e641400SJames Smart 
23*3e641400SJames Smart /* efct_scsi_send_rd_data/recv_wr_data/send_resp flags */
24*3e641400SJames Smart #define EFCT_SCSI_LAST_DATAPHASE	(1 << 0)
25*3e641400SJames Smart #define EFCT_SCSI_NO_AUTO_RESPONSE	(1 << 1)
26*3e641400SJames Smart #define EFCT_SCSI_LOW_LATENCY		(1 << 2)
27*3e641400SJames Smart 
28*3e641400SJames Smart #define EFCT_SCSI_SNS_BUF_VALID(sense)	((sense) && \
29*3e641400SJames Smart 			(0x70 == (((const u8 *)(sense))[0] & 0x70)))
30*3e641400SJames Smart 
31*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_SHIFT	16
32*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_MASK	(0xf << EFCT_SCSI_WQ_STEERING_SHIFT)
33*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_CLASS	(0 << EFCT_SCSI_WQ_STEERING_SHIFT)
34*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_REQUEST	(1 << EFCT_SCSI_WQ_STEERING_SHIFT)
35*3e641400SJames Smart #define EFCT_SCSI_WQ_STEERING_CPU	(2 << EFCT_SCSI_WQ_STEERING_SHIFT)
36*3e641400SJames Smart 
37*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_SHIFT		(20)
38*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_MASK		(0xf << EFCT_SCSI_WQ_CLASS_SHIFT)
39*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS(x)		((x & EFCT_SCSI_WQ_CLASS_MASK) << \
40*3e641400SJames Smart 						EFCT_SCSI_WQ_CLASS_SHIFT)
41*3e641400SJames Smart 
42*3e641400SJames Smart #define EFCT_SCSI_WQ_CLASS_LOW_LATENCY	1
43*3e641400SJames Smart 
44*3e641400SJames Smart struct efct_scsi_cmd_resp {
45*3e641400SJames Smart 	u8 scsi_status;
46*3e641400SJames Smart 	u16 scsi_status_qualifier;
47*3e641400SJames Smart 	u8 *response_data;
48*3e641400SJames Smart 	u32 response_data_length;
49*3e641400SJames Smart 	u8 *sense_data;
50*3e641400SJames Smart 	u32 sense_data_length;
51*3e641400SJames Smart 	int residual;
52*3e641400SJames Smart 	u32 response_wire_length;
53*3e641400SJames Smart };
54*3e641400SJames Smart 
55*3e641400SJames Smart struct efct_vport {
56*3e641400SJames Smart 	struct efct		*efct;
57*3e641400SJames Smart 	bool			is_vport;
58*3e641400SJames Smart 	struct fc_host_statistics fc_host_stats;
59*3e641400SJames Smart 	struct Scsi_Host	*shost;
60*3e641400SJames Smart 	struct fc_vport		*fc_vport;
61*3e641400SJames Smart 	u64			npiv_wwpn;
62*3e641400SJames Smart 	u64			npiv_wwnn;
63*3e641400SJames Smart };
64*3e641400SJames Smart 
65*3e641400SJames Smart /* Status values returned by IO callbacks */
66*3e641400SJames Smart enum efct_scsi_io_status {
67*3e641400SJames Smart 	EFCT_SCSI_STATUS_GOOD = 0,
68*3e641400SJames Smart 	EFCT_SCSI_STATUS_ABORTED,
69*3e641400SJames Smart 	EFCT_SCSI_STATUS_ERROR,
70*3e641400SJames Smart 	EFCT_SCSI_STATUS_DIF_GUARD_ERR,
71*3e641400SJames Smart 	EFCT_SCSI_STATUS_DIF_REF_TAG_ERROR,
72*3e641400SJames Smart 	EFCT_SCSI_STATUS_DIF_APP_TAG_ERROR,
73*3e641400SJames Smart 	EFCT_SCSI_STATUS_DIF_UNKNOWN_ERROR,
74*3e641400SJames Smart 	EFCT_SCSI_STATUS_PROTOCOL_CRC_ERROR,
75*3e641400SJames Smart 	EFCT_SCSI_STATUS_NO_IO,
76*3e641400SJames Smart 	EFCT_SCSI_STATUS_ABORT_IN_PROGRESS,
77*3e641400SJames Smart 	EFCT_SCSI_STATUS_CHECK_RESPONSE,
78*3e641400SJames Smart 	EFCT_SCSI_STATUS_COMMAND_TIMEOUT,
79*3e641400SJames Smart 	EFCT_SCSI_STATUS_TIMEDOUT_AND_ABORTED,
80*3e641400SJames Smart 	EFCT_SCSI_STATUS_SHUTDOWN,
81*3e641400SJames Smart 	EFCT_SCSI_STATUS_NEXUS_LOST,
82*3e641400SJames Smart };
83*3e641400SJames Smart 
84*3e641400SJames Smart struct efct_node;
85*3e641400SJames Smart struct efct_io;
86*3e641400SJames Smart struct efc_node;
87*3e641400SJames Smart struct efc_nport;
88*3e641400SJames Smart 
89*3e641400SJames Smart /* Callback used by send_rd_data(), recv_wr_data(), send_resp() */
90*3e641400SJames Smart typedef int (*efct_scsi_io_cb_t)(struct efct_io *io,
91*3e641400SJames Smart 				    enum efct_scsi_io_status status,
92*3e641400SJames Smart 				    u32 flags, void *arg);
93*3e641400SJames Smart 
94*3e641400SJames Smart /* Callback used by send_rd_io(), send_wr_io() */
95*3e641400SJames Smart typedef int (*efct_scsi_rsp_io_cb_t)(struct efct_io *io,
96*3e641400SJames Smart 			enum efct_scsi_io_status status,
97*3e641400SJames Smart 			struct efct_scsi_cmd_resp *rsp,
98*3e641400SJames Smart 			u32 flags, void *arg);
99*3e641400SJames Smart 
100*3e641400SJames Smart /* efct_scsi_cb_t flags */
101*3e641400SJames Smart #define EFCT_SCSI_IO_CMPL		(1 << 0)
102*3e641400SJames Smart /* IO completed, response sent */
103*3e641400SJames Smart #define EFCT_SCSI_IO_CMPL_RSP_SENT	(1 << 1)
104*3e641400SJames Smart #define EFCT_SCSI_IO_ABORTED		(1 << 2)
105*3e641400SJames Smart 
106*3e641400SJames Smart /* efct_scsi_recv_tmf() request values */
107*3e641400SJames Smart enum efct_scsi_tmf_cmd {
108*3e641400SJames Smart 	EFCT_SCSI_TMF_ABORT_TASK = 1,
109*3e641400SJames Smart 	EFCT_SCSI_TMF_QUERY_TASK_SET,
110*3e641400SJames Smart 	EFCT_SCSI_TMF_ABORT_TASK_SET,
111*3e641400SJames Smart 	EFCT_SCSI_TMF_CLEAR_TASK_SET,
112*3e641400SJames Smart 	EFCT_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT,
113*3e641400SJames Smart 	EFCT_SCSI_TMF_LOGICAL_UNIT_RESET,
114*3e641400SJames Smart 	EFCT_SCSI_TMF_CLEAR_ACA,
115*3e641400SJames Smart 	EFCT_SCSI_TMF_TARGET_RESET,
116*3e641400SJames Smart };
117*3e641400SJames Smart 
118*3e641400SJames Smart /* efct_scsi_send_tmf_resp() response values */
119*3e641400SJames Smart enum efct_scsi_tmf_resp {
120*3e641400SJames Smart 	EFCT_SCSI_TMF_FUNCTION_COMPLETE = 1,
121*3e641400SJames Smart 	EFCT_SCSI_TMF_FUNCTION_SUCCEEDED,
122*3e641400SJames Smart 	EFCT_SCSI_TMF_FUNCTION_IO_NOT_FOUND,
123*3e641400SJames Smart 	EFCT_SCSI_TMF_FUNCTION_REJECTED,
124*3e641400SJames Smart 	EFCT_SCSI_TMF_INCORRECT_LOGICAL_UNIT_NUMBER,
125*3e641400SJames Smart 	EFCT_SCSI_TMF_SERVICE_DELIVERY,
126*3e641400SJames Smart };
127*3e641400SJames Smart 
128*3e641400SJames Smart struct efct_scsi_sgl {
129*3e641400SJames Smart 	uintptr_t	addr;
130*3e641400SJames Smart 	uintptr_t	dif_addr;
131*3e641400SJames Smart 	size_t		len;
132*3e641400SJames Smart };
133*3e641400SJames Smart 
134*3e641400SJames Smart enum efct_scsi_io_role {
135*3e641400SJames Smart 	EFCT_SCSI_IO_ROLE_ORIGINATOR,
136*3e641400SJames Smart 	EFCT_SCSI_IO_ROLE_RESPONDER,
137*3e641400SJames Smart };
138*3e641400SJames Smart 
139*3e641400SJames Smart struct efct_io *
140*3e641400SJames Smart efct_scsi_io_alloc(struct efct_node *node);
141*3e641400SJames Smart void efct_scsi_io_free(struct efct_io *io);
142*3e641400SJames Smart struct efct_io *efct_io_get_instance(struct efct *efct, u32 index);
143*3e641400SJames Smart 
144*3e641400SJames Smart int efct_scsi_tgt_driver_init(void);
145*3e641400SJames Smart int efct_scsi_tgt_driver_exit(void);
146*3e641400SJames Smart int efct_scsi_tgt_new_device(struct efct *efct);
147*3e641400SJames Smart int efct_scsi_tgt_del_device(struct efct *efct);
148*3e641400SJames Smart int
149*3e641400SJames Smart efct_scsi_tgt_new_nport(struct efc *efc, struct efc_nport *nport);
150*3e641400SJames Smart void
151*3e641400SJames Smart efct_scsi_tgt_del_nport(struct efc *efc, struct efc_nport *nport);
152*3e641400SJames Smart 
153*3e641400SJames Smart int
154*3e641400SJames Smart efct_scsi_new_initiator(struct efc *efc, struct efc_node *node);
155*3e641400SJames Smart 
156*3e641400SJames Smart enum efct_scsi_del_initiator_reason {
157*3e641400SJames Smart 	EFCT_SCSI_INITIATOR_DELETED,
158*3e641400SJames Smart 	EFCT_SCSI_INITIATOR_MISSING,
159*3e641400SJames Smart };
160*3e641400SJames Smart 
161*3e641400SJames Smart int
162*3e641400SJames Smart efct_scsi_del_initiator(struct efc *efc, struct efc_node *node,	int reason);
163*3e641400SJames Smart void
164*3e641400SJames Smart efct_scsi_recv_cmd(struct efct_io *io, uint64_t lun, u8 *cdb, u32 cdb_len,
165*3e641400SJames Smart 		   u32 flags);
166*3e641400SJames Smart int
167*3e641400SJames Smart efct_scsi_recv_tmf(struct efct_io *tmfio, u32 lun, enum efct_scsi_tmf_cmd cmd,
168*3e641400SJames Smart 		   struct efct_io *abortio, u32 flags);
169*3e641400SJames Smart int
170*3e641400SJames Smart efct_scsi_send_rd_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl,
171*3e641400SJames Smart 		u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg);
172*3e641400SJames Smart int
173*3e641400SJames Smart efct_scsi_recv_wr_data(struct efct_io *io, u32 flags, struct efct_scsi_sgl *sgl,
174*3e641400SJames Smart 		u32 sgl_count, u64 wire_len, efct_scsi_io_cb_t cb, void *arg);
175*3e641400SJames Smart int
176*3e641400SJames Smart efct_scsi_send_resp(struct efct_io *io, u32 flags,
177*3e641400SJames Smart 		struct efct_scsi_cmd_resp *rsp, efct_scsi_io_cb_t cb, void *arg);
178*3e641400SJames Smart int
179*3e641400SJames Smart efct_scsi_send_tmf_resp(struct efct_io *io, enum efct_scsi_tmf_resp rspcode,
180*3e641400SJames Smart 			u8 addl_rsp_info[3], efct_scsi_io_cb_t cb, void *arg);
181*3e641400SJames Smart int
182*3e641400SJames Smart efct_scsi_tgt_abort_io(struct efct_io *io, efct_scsi_io_cb_t cb, void *arg);
183*3e641400SJames Smart 
184*3e641400SJames Smart void efct_scsi_io_complete(struct efct_io *io);
185*3e641400SJames Smart 
186*3e641400SJames Smart int efct_scsi_reg_fc_transport(void);
187*3e641400SJames Smart void efct_scsi_release_fc_transport(void);
188*3e641400SJames Smart int efct_scsi_new_device(struct efct *efct);
189*3e641400SJames Smart void efct_scsi_del_device(struct efct *efct);
190*3e641400SJames Smart void _efct_scsi_io_free(struct kref *arg);
191*3e641400SJames Smart 
192*3e641400SJames Smart int
193*3e641400SJames Smart efct_scsi_del_vport(struct efct *efct, struct Scsi_Host *shost);
194*3e641400SJames Smart struct efct_vport *
195*3e641400SJames Smart efct_scsi_new_vport(struct efct *efct, struct device *dev);
196*3e641400SJames Smart 
197*3e641400SJames Smart int efct_scsi_io_dispatch(struct efct_io *io, void *cb);
198*3e641400SJames Smart int efct_scsi_io_dispatch_abort(struct efct_io *io, void *cb);
199*3e641400SJames Smart void efct_scsi_check_pending(struct efct *efct);
200*3e641400SJames Smart struct efct_io *
201*3e641400SJames Smart efct_bls_send_rjt(struct efct_io *io, struct fc_frame_header *hdr);
202*3e641400SJames Smart 
203*3e641400SJames Smart #endif /* __EFCT_SCSI_H__ */
204