summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fct.h
blob: 0960bbfb974faf9eeae280ab828fe83590f1c11e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
 * Copyright 2020 RackTop Systems, Inc.
 */
#ifndef	_FCT_H
#define	_FCT_H

/*
 * Definitions for common FC Target.
 */
#include <sys/note.h>
#include <sys/stmf_defines.h>
#include <sys/fct_defines.h>
#include <sys/portif.h>

#ifdef	__cplusplus
extern "C" {
#endif

typedef enum fct_struct_id {
	FCT_STRUCT_LOCAL_PORT = 1,
	FCT_STRUCT_REMOTE_PORT,
	FCT_STRUCT_CMD_RCVD_ELS,
	FCT_STRUCT_CMD_SOL_ELS,
	FCT_STRUCT_CMD_SOL_CT,
	FCT_STRUCT_CMD_RCVD_ABTS,
	FCT_STRUCT_CMD_FCP_XCHG,
	FCT_STRUCT_DBUF_STORE,

	FCT_MAX_STRUCT_IDS
} fct_struct_id_t;

typedef struct fct_remote_port {
	void		*rp_fct_private;
	void		*rp_fca_private;

	struct fct_local_port *rp_port;
	char		rp_nwwn_str[FC_WWN_BUFLEN];
	char		rp_pwwn_str[FC_WWN_BUFLEN];
	uint8_t		rp_nwwn[FC_WWN_LEN];
	uint8_t		rp_pwwn[FC_WWN_LEN];
	uint32_t	rp_id;		/* 8 or 24 bit */
	uint32_t	rp_hard_address;
	uint16_t	rp_handle;
} fct_remote_port_t;

#define	FCT_HANDLE_NONE	0xffff

typedef struct fct_cmd {
	void		*cmd_fct_private;
	void		*cmd_fca_private;
	void		*cmd_specific;

	struct fct_local_port	*cmd_port;

	/* During cmd porting this can be set to NULL */
	struct fct_remote_port	*cmd_rp;

	/* To link cmds together for handling things like ABTS. */
	struct fct_cmd	*cmd_link;
	uint8_t		cmd_type;
	uint8_t		cmd_rsvd1;

	/* During cmd posting this can be set to FCT_HANDLE_NONE */
	uint16_t	cmd_rp_handle;
	uint32_t	cmd_handle;
	uint32_t	cmd_rportid;
	uint32_t	cmd_lportid;
	uint32_t	cmd_rsvd2;
	uint16_t	cmd_oxid;
	uint16_t	cmd_rxid;
	fct_status_t	cmd_comp_status;
} fct_cmd_t;

/*
 * fcmd_cmd_handle: Bit definitions.
 *   31		  23	       15	    7	       0
 *  +--------------+------------+------------+------------+
 *  | V |uniq_cntr |fca specific|   cmd slot index	  |
 *  +--------------+------------+------------+------------+
 * V = handle valid.
 */
#define	CMD_HANDLE_SLOT_INDEX(x)	((x) & 0xffff)
#define	CMD_HANDLE_VALID(x)		((x) & 0x80000000)

enum fct_cmd_types {
	FCT_CMD_FCP_XCHG =	0x0001,
	FCT_CMD_RCVD_ELS =	0x0002,
	FCT_CMD_SOL_ELS =	0x0004,
	FCT_CMD_RCVD_ABTS =	0x0008,
	FCT_CMD_SOL_CT =	0x0010,

	FCT_CMD_TYPE_ALL =	0xffff
};

typedef struct fct_els {
	uint16_t	els_req_size;
	uint16_t	els_resp_size;
	uint16_t	els_req_alloc_size;
	uint16_t	els_resp_alloc_size;
	uint8_t		*els_req_payload;
	uint8_t		*els_resp_payload;
} fct_els_t;

typedef struct fct_sol_ct {
	uint16_t	ct_req_size;
	uint16_t	ct_resp_size;
	uint16_t	ct_req_alloc_size;
	uint16_t	ct_resp_alloc_size;
	uint8_t		*ct_req_payload;
	uint8_t		*ct_resp_payload;
} fct_sol_ct_t;

typedef struct fct_rcvd_abts {
	uint8_t		abts_resp_rctl;	/* Can be BA_ACC or BA_RJT */
	uint8_t		abts_state;
	uint16_t	rsvd;
	uint8_t		abts_resp_payload[12];
} fct_rcvd_abts_t;

/*
 * abts state
 */
#define	ABTS_STATE_RECEIVED		0
#define	ABTS_STATE_RESPONDED		1
#define	ABTS_STATE_COMPLETED		2
#define	ABTS_STATE_ABORT_REQUESTED	3
#define	ABTS_STATE_ABORT_COMPLETED	4

#define	FCHBA_MANUFACTURER_LEN		64
#define	FCHBA_SERIAL_NUMBER_LEN		64
#define	FCHBA_MODEL_LEN			256
#define	FCHBA_MODEL_DESCRIPTION_LEN	256
#define	FCHBA_HARDWARE_VERSION_LEN	256
#define	FCHBA_DRIVER_VERSION_LEN	256
#define	FCHBA_OPTION_ROM_VERSION_LEN	256
#define	FCHBA_FIRMWARE_VERSION_LEN	256
#define	FCHBA_DRIVER_NAME_LEN		256
#define	FCHBA_SYMB_NAME_LEN		255

#define	FCT_INFO_LEN			160
#define	FCT_TASKQ_NAME_LEN		24

#define	FC_TGT_PORT_INFO_CMD		(((uint32_t)'I') << 24)
#define	FC_TGT_PORT_RLS			FC_TGT_PORT_INFO_CMD + 0x1

typedef struct fct_port_attrs {
	char		manufacturer[FCHBA_MANUFACTURER_LEN];
	char		serial_number[FCHBA_SERIAL_NUMBER_LEN];
	char		model[FCHBA_MODEL_LEN];
	char		model_description[FCHBA_MODEL_DESCRIPTION_LEN];
	char		hardware_version[FCHBA_HARDWARE_VERSION_LEN];
	char		driver_version[FCHBA_DRIVER_VERSION_LEN];
	char		option_rom_version[FCHBA_OPTION_ROM_VERSION_LEN];
	char		firmware_version[FCHBA_FIRMWARE_VERSION_LEN];
	char		driver_name[FCHBA_DRIVER_NAME_LEN];
	uint32_t	vendor_specific_id;
	uint32_t	supported_cos;
	uint32_t	supported_speed;
	uint32_t	max_frame_size;
} fct_port_attrs_t;

typedef struct fct_port_link_status {
	uint32_t	LinkFailureCount;
	uint32_t	LossOfSyncCount;
	uint32_t	LossOfSignalsCount;
	uint32_t	PrimitiveSeqProtocolErrorCount;
	uint32_t	InvalidTransmissionWordCount;
	uint32_t	InvalidCRCCount;
} fct_port_link_status_t;

typedef struct fct_dbuf_store {
	void			*fds_fct_private;
	void			*fds_fca_private;
	struct stmf_dbuf_store	*fds_ds;

	stmf_data_buf_t *(*fds_alloc_data_buf)(struct fct_local_port *port,
			    uint32_t size, uint32_t *pminsize, uint32_t flags);
	void		(*fds_free_data_buf)(struct fct_dbuf_store *fds,
			    stmf_data_buf_t *dbuf);
	stmf_status_t	(*fds_setup_dbuf)(struct fct_local_port *port,
			    stmf_data_buf_t *dbuf, uint32_t flags);
	void		(*fds_teardown_dbuf)(struct fct_dbuf_store *fds,
			    stmf_data_buf_t *dbuf);

	uint32_t		fds_max_sgl_xfer_len;
	uint32_t		fds_copy_threshold;
} fct_dbuf_store_t;

#define	FCT_FCA_MODREV_1	1

typedef struct fct_local_port {
	void			*port_fct_private;
	void			*port_fca_private;
	stmf_local_port_t	*port_lport;

	char			port_nwwn_str[FC_WWN_BUFLEN];
	char			port_pwwn_str[FC_WWN_BUFLEN];
	uint8_t			port_nwwn[FC_WWN_LEN];
	uint8_t			port_pwwn[FC_WWN_LEN];
	char			*port_default_alias;
	char			*port_sym_node_name;
	char			*port_sym_port_name;

	stmf_port_provider_t	*port_pp;

	uint32_t		port_hard_address;
	uint16_t		port_max_logins;
	uint16_t		port_max_xchges;
	uint32_t		port_fca_fcp_cmd_size;
	uint32_t		port_fca_rp_private_size;
	uint32_t		port_fca_sol_els_private_size;
	uint32_t		port_fca_sol_ct_private_size;

	/* in milliseconds */
	uint32_t		port_fca_abort_timeout;

	fct_dbuf_store_t	*port_fds;
	fct_status_t		(*port_get_link_info)(
		struct fct_local_port *port, struct fct_link_info *li);
	fct_status_t		(*port_register_remote_port)(
		struct fct_local_port *port, struct fct_remote_port *rp,
		struct fct_cmd *login_els);
	fct_status_t		(*port_deregister_remote_port)(
		struct fct_local_port *port, struct fct_remote_port *rp);
	fct_status_t		(*port_send_cmd)(fct_cmd_t *cmd);
	fct_status_t		(*port_xfer_scsi_data)(fct_cmd_t *cmd,
			stmf_data_buf_t *dbuf, uint32_t flags);
	fct_status_t		(*port_send_cmd_response)(fct_cmd_t *cmd,
					uint32_t ioflags);
	fct_status_t		(*port_abort_cmd)(struct fct_local_port *port,
			fct_cmd_t *cmd, uint32_t flags);
	void			(*port_ctl)(struct fct_local_port *port,
						int cmd, void *arg);
	fct_status_t		(*port_flogi_xchg)(struct fct_local_port *port,
			struct fct_flogi_xchg *fx);
	void			(*port_populate_hba_details)(
		struct fct_local_port *port, struct fct_port_attrs *port_attrs);
	fct_status_t		(*port_info)(uint32_t cmd,
		struct fct_local_port *port, void *arg, uint8_t *buf,
		uint32_t *bufsizep);
	int		port_fca_version;
} fct_local_port_t;

/*
 * Common struct used during FLOGI exchange.
 */
typedef struct fct_flogi_xchg {
	uint8_t		fx_op;		/* ELS_OP_FLOGI or ELS_OP_ACC/RJT */
	uint8_t		fx_rjt_reason;
	uint8_t		fx_rjt_expl;
	uint8_t		fx_sec_timeout;	/* Timeout in seconds */
	uint32_t	fx_fport:1,	/* 0=N_port, 1=F_port */
			rsvd2:31;
	uint32_t	fx_sid;		/* 24 bit SID to use */
	uint32_t	fx_did;		/* 24 bit DID to use */
	uint8_t		fx_pwwn[8];
	uint8_t		fx_nwwn[8];
} fct_flogi_xchg_t;

typedef struct fct_link_info {
	uint32_t		portid;
	uint8_t			port_topology;
	uint8_t			port_speed;

	uint8_t			rsvd:5,

	/*
	 * FCA sets this bit to indicate that fct does not need to do FLOGI
	 * because either FCA did the FLOGI or it determined that its a private
	 * loop. Setting this bit by FCA is optional.
	 */
				port_no_fct_flogi:1,

	/* FCA sets this bit to indicate that it did FLOGI */
				port_fca_flogi_done:1,

	/* FCT sets this bit to indicate that it did FLOGI */
				port_fct_flogi_done:1;

	uint8_t			rsvd1;

	/* The fields below are only valid if someone did a successful flogi */
	uint8_t			port_rnwwn[8];
	uint8_t			port_rpwwn[8];
} fct_link_info_t;

typedef struct fct_port_stat {
	kstat_named_t	link_failure_cnt;
	kstat_named_t	loss_of_sync_cnt;
	kstat_named_t	loss_of_signals_cnt;
	kstat_named_t	prim_seq_protocol_err_cnt;
	kstat_named_t	invalid_tx_word_cnt;
	kstat_named_t	invalid_crc_cnt;
} fct_port_stat_t;

/*
 * port topology
 */
#define	PORT_TOPOLOGY_UNKNOWN		0
#define	PORT_TOPOLOGY_PT_TO_PT		1
#define	PORT_TOPOLOGY_PRIVATE_LOOP	2
#define	PORT_TOPOLOGY_PUBLIC_LOOP	6
#define	PORT_TOPOLOGY_FABRIC_PT_TO_PT	5
#define	PORT_TOPOLOGY_FABRIC_BIT	4

#define	PORT_FLOGI_DONE(li)	(((li)->port_fca_flogi_done) || \
					((li)->port_fct_flogi_done))

/*
 * port speed
 */
#define	PORT_SPEED_UNKNOWN		0
#define	PORT_SPEED_1G			1
#define	PORT_SPEED_2G			2
#define	PORT_SPEED_4G			4
#define	PORT_SPEED_8G			8
#define	PORT_SPEED_10G			16
#define	PORT_SPEED_16G			32
#define	PORT_SPEED_32G			64

/*
 * Abort commands
 */
#define	FCT_TERMINATE_CMD		1

/*
 * FCT port states.
 */
#define	FCT_STATE_OFFLINE	0
#define	FCT_STATE_ONLINING	1
#define	FCT_STATE_ONLINE	2
#define	FCT_STATE_OFFLINING	3

/*
 * fct ctl commands. These should not conflict with stmf ctl commands
 */
#define	FCT_CMD_PORT_ONLINE		(STMF_LPORT_CTL_CMDS | 0x01)
#define	FCT_CMD_PORT_ONLINE_COMPLETE	(STMF_LPORT_CTL_CMDS | 0x02)
#define	FCT_CMD_PORT_OFFLINE		(STMF_LPORT_CTL_CMDS | 0x03)
#define	FCT_CMD_PORT_OFFLINE_COMPLETE	(STMF_LPORT_CTL_CMDS | 0x04)
#define	FCT_ACK_PORT_ONLINE_COMPLETE	(STMF_LPORT_CTL_CMDS | 0x05)
#define	FCT_ACK_PORT_OFFLINE_COMPLETE	(STMF_LPORT_CTL_CMDS | 0x06)
#define	FCT_CMD_FORCE_LIP		(STMF_LPORT_CTL_CMDS | 0x07)

/*
 * IO flags for cmd flow.
 */
#define	FCT_IOF_FCA_DONE		0x10000
#define	FCT_IOF_FORCE_FCA_DONE		0x20000

/*
 * Fill CTIU preamble
 */
#ifdef	lint
#define	FCT_FILL_CTIU_PREAMBLE(x_payload, x_ctop)	_NOTE(EMPTY)
#else
#define	FCT_FILL_CTIU_PREAMBLE(x_payload, x_ctop)	\
	do {						\
		x_payload[0] = 0x01;			\
		x_payload[4] = 0xFC;			\
		x_payload[5] = 0x02;			\
		x_payload[8] = 0xFF & (x_ctop >> 8);	\
		x_payload[9] = 0xFF & (x_ctop);		\
	} while (0)
#endif

uint64_t fct_netbuf_to_value(uint8_t *buf, uint8_t nbytes);
void fct_value_to_netbuf(uint64_t value, uint8_t *buf, uint8_t nbytes);
void *fct_alloc(fct_struct_id_t struct_id, int additional_size, int flags);
void fct_free(void *ptr);
fct_cmd_t *fct_scsi_task_alloc(struct fct_local_port *port,
    uint16_t rp_handle, uint32_t rportid, uint8_t *lun,
    uint16_t cdb_length, uint16_t task_ext);
fct_status_t fct_register_local_port(fct_local_port_t *port);
fct_status_t fct_deregister_local_port(fct_local_port_t *port);
void fct_handle_event(fct_local_port_t *port, int event_id,
    uint32_t event_flags, caddr_t arg);
void fct_post_rcvd_cmd(fct_cmd_t *cmd, stmf_data_buf_t *dbuf);
void fct_queue_cmd_for_termination(fct_cmd_t *cmd, fct_status_t s);
void fct_queue_scsi_task_for_termination(fct_cmd_t *cmd, fct_status_t s);
fct_cmd_t *fct_handle_to_cmd(fct_local_port_t *port, uint32_t fct_handle);
void fct_ctl(struct stmf_local_port *lport, int cmd, void *arg);
void fct_cmd_fca_aborted(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags);
uint16_t fct_get_rp_handle(fct_local_port_t *port, uint32_t rportid);
void fct_send_response_done(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags);
void fct_send_cmd_done(fct_cmd_t *cmd, fct_status_t s, uint32_t ioflags);
void fct_scsi_data_xfer_done(fct_cmd_t *cmd, stmf_data_buf_t *dbuf,
    uint32_t ioflags);
fct_status_t fct_port_initialize(fct_local_port_t *port, uint32_t rflags,
    char *additional_info);
fct_status_t fct_port_shutdown(fct_local_port_t *port, uint32_t rflags,
    char *additional_info);
fct_status_t fct_handle_rcvd_flogi(fct_local_port_t *port,
    fct_flogi_xchg_t *fx);
void fct_log_local_port_event(fct_local_port_t *port, char *subclass);
void fct_log_remote_port_event(fct_local_port_t *port, char *subclass,
    uint8_t *rp_pwwn, uint32_t rp_id);
void fct_wwn_to_str(char *to_ptr, const uint8_t *from_ptr);

#ifdef	__cplusplus
}
#endif

#endif /* _FCT_H */