1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Emulex.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _EMLXS_FC_H
28 #define	_EMLXS_FC_H
29 
30 #ifdef	__cplusplus
31 extern "C" {
32 #endif
33 
34 typedef struct emlxs_buf
35 {
36 	fc_packet_t		*pkt;		/* scsi_pkt reference */
37 	struct emlxs_port	*port;		/* pointer to port */
38 	void			*bmp;		/* Save the buffer pointer */
39 						/* list for later use. */
40 	struct emlxs_buf	*fc_fwd;	/* Use it by chip_Q */
41 	struct emlxs_buf	*fc_bkwd;	/* Use it by chip_Q */
42 	struct emlxs_buf	*next;		/* Use it when the iodone */
43 	void 			*node;		/* Save node and used by */
44 						/* abort */
45 	void			*channel;	/* Save channel and used by */
46 						/* abort */
47 	struct emlxs_buf	*fpkt;		/* Flush pkt pointer */
48 	struct XRIobject	*xp;		/* Exchange resource */
49 	IOCBQ			iocbq;
50 	kmutex_t		mtx;
51 	uint32_t		pkt_flags;
52 	uint32_t		iotag;		/* iotag for this cmd */
53 	uint32_t		ticks;		/* save the timeout ticks */
54 						/* for the fc_packet_t */
55 	uint32_t		abort_attempts;
56 	uint32_t		lun;		/* Save LUN id and used by */
57 						/* abort */
58 	uint32_t		class;		/* Save class and used by */
59 						/* abort */
60 	uint32_t		ucmd;		/* Unsolicted command that */
61 						/* this packet is responding */
62 						/* to, if any */
63 	int32_t			flush_count;	/* Valid only in flush pkts */
64 	uint32_t		did;
65 
66 #ifdef SFCT_SUPPORT
67 	kmutex_t		fct_mtx;
68 	fc_packet_t		*fct_pkt;
69 	fct_cmd_t		*fct_cmd;
70 
71 	uint8_t			fct_type;
72 
73 #define	EMLXS_FCT_ELS_CMD		0x01	/* Unsolicted */
74 #define	EMLXS_FCT_ELS_REQ		0x02	/* Solicited */
75 #define	EMLXS_FCT_ELS_RSP		0x04
76 #define	EMLXS_FCT_CT_REQ		0x08	/* Solicited */
77 #define	EMLXS_FCT_FCP_CMD		0x10	/* Unsolicted */
78 #define	EMLXS_FCT_FCP_DATA		0x20
79 #define	EMLXS_FCT_FCP_STATUS		0x40
80 
81 
82 	uint8_t			fct_flags;
83 
84 #define	EMLXS_FCT_SEND_STATUS		0x01
85 #define	EMLXS_FCT_ABORT_INP		0x02
86 #define	EMLXS_FCT_IO_INP		0x04
87 #define	EMLXS_FCT_REGISTERED		0x10
88 #define	EMLXS_FCT_PLOGI_RECEIVED	0x20
89 #define	EMLXS_FCT_FLOGI			0x40
90 
91 	uint16_t		fct_state;
92 
93 #define	EMLXS_FCT_FCP_CMD_RECEIVED	1
94 #define	EMLXS_FCT_ELS_CMD_RECEIVED	2
95 #define	EMLXS_FCT_CMD_POSTED		3
96 #define	EMLXS_FCT_CMD_WAITQ		4
97 #define	EMLXS_FCT_SEND_CMD_RSP		5
98 #define	EMLXS_FCT_SEND_ELS_RSP		6
99 #define	EMLXS_FCT_SEND_ELS_REQ		7
100 #define	EMLXS_FCT_SEND_CT_REQ		8
101 #define	EMLXS_FCT_RSP_PENDING		9
102 #define	EMLXS_FCT_REQ_PENDING		10
103 #define	EMLXS_FCT_REG_PENDING		11
104 #define	EMLXS_FCT_REG_COMPLETE		12
105 #define	EMLXS_FCT_OWNED			13
106 #define	EMLXS_FCT_SEND_FCP_DATA		14
107 #define	EMLXS_FCT_SEND_FCP_STATUS	15
108 #define	EMLXS_FCT_DATA_PENDING		16
109 #define	EMLXS_FCT_STATUS_PENDING	17
110 #define	EMLXS_FCT_PKT_COMPLETE		18
111 #define	EMLXS_FCT_PKT_FCPRSP_COMPLETE	19
112 #define	EMLXS_FCT_PKT_ELSRSP_COMPLETE	20
113 #define	EMLXS_FCT_PKT_ELSCMD_COMPLETE	21
114 #define	EMLXS_FCT_PKT_CTCMD_COMPLETE	22
115 #define	EMLXS_FCT_REQ_COMPLETE		23
116 #define	EMLXS_FCT_CLOSE_PENDING		24
117 #define	EMLXS_FCT_ABORT_PENDING		25
118 #define	EMLXS_FCT_ABORT_DONE		26
119 #define	EMLXS_FCT_IO_DONE		27
120 
121 #define	EMLXS_FCT_IOCB_ISSUED		256 /* For tracing only */
122 #define	EMLXS_FCT_IOCB_COMPLETE		257 /* For tracing only */
123 
124 	stmf_data_buf_t		*fct_buf;
125 
126 #endif /* SFCT_SUPPORT */
127 
128 #ifdef SAN_DIAG_SUPPORT
129 	hrtime_t		sd_start_time;
130 #endif
131 } emlxs_buf_t;
132 
133 
134 
135 #ifdef FCT_IO_TRACE
136 #define	EMLXS_FCT_STATE_CHG(_fct_cmd, _cmd_sbp, _state)	\
137 	(_cmd_sbp)->fct_state = _state;			\
138 	emlxs_fct_io_trace((_cmd_sbp)->port, _fct_cmd, _state)
139 #else
140 /* define to set fct_state */
141 #define	EMLXS_FCT_STATE_CHG(_fct_cmd, _cmd_sbp, _state)	\
142 	(_cmd_sbp)->fct_state = _state
143 #endif /* FCT_IO_TRACE */
144 
145 
146 /* pkt_flags */
147 #define	PACKET_IN_COMPLETION	0x00000001
148 #define	PACKET_IN_TXQ		0x00000002
149 #define	PACKET_IN_CHIPQ		0x00000004
150 #define	PACKET_IN_DONEQ		0x00000008
151 
152 #define	PACKET_FCP_RESET	0x00000030
153 #define	PACKET_FCP_TGT_RESET	0x00000010
154 #define	PACKET_FCP_LUN_RESET	0x00000020
155 #define	PACKET_POLLED		0x00000040
156 
157 #ifdef EMLXS_I386
158 #define	PACKET_FCP_SWAPPED	0x00000100
159 #define	PACKET_ELS_SWAPPED	0x00000200
160 #define	PACKET_CT_SWAPPED	0x00000400
161 #define	PACKET_CSP_SWAPPED	0x00000800
162 #endif	/* EMLXS_I386 */
163 
164 #define	PACKET_STALE		0x00001000
165 
166 #define	PACKET_IN_TIMEOUT	0x00010000
167 #define	PACKET_IN_FLUSH		0x00020000
168 #define	PACKET_IN_ABORT		0x00040000
169 #define	PACKET_XRI_CLOSED	0x00080000 /* An XRI abort/close was issued */
170 
171 #define	PACKET_CHIP_COMP	0x00100000
172 #define	PACKET_COMPLETED	0x00200000
173 #define	PACKET_ULP_OWNED	0x00400000
174 
175 #define	PACKET_STATE_VALID	0x01000000
176 #define	PACKET_FCP_RSP_VALID	0x02000000
177 #define	PACKET_ELS_RSP_VALID	0x04000000
178 #define	PACKET_CT_RSP_VALID	0x08000000
179 
180 #define	PACKET_DELAY_REQUIRED	0x10000000
181 #define	PACKET_ALLOCATED	0x40000000
182 #define	PACKET_VALID		0x80000000
183 
184 
185 #define	STALE_PACKET		((emlxs_buf_t *)0xFFFFFFFF)
186 
187 
188 /*
189  * From fc_error.h pkt_reason (except for state = NPORT_RJT, FABRIC_RJT,
190  * NPORT_BSY, FABRIC_BSY, LS_RJT, BA_RJT, FS_RJT)
191  *
192  * FCA unique error codes can begin after FC_REASON_FCA_UNIQUE.
193  * Each FCA defines its own set with values greater >= 0x7F
194  */
195 #define	FC_REASON_FCA_DEFINED   0x100
196 
197 
198 /*
199  * Device VPD save area
200  */
201 
202 typedef struct emlxs_vpd
203 {
204 	uint32_t	biuRev;
205 	uint32_t	smRev;
206 	uint32_t	smFwRev;
207 	uint32_t	endecRev;
208 	uint16_t	rBit;
209 	uint8_t		fcphHigh;
210 	uint8_t		fcphLow;
211 	uint8_t		feaLevelHigh;
212 	uint8_t		feaLevelLow;
213 
214 	uint32_t	postKernRev;
215 	char		postKernName[32];
216 
217 	uint32_t	opFwRev;
218 	char		opFwName[32];
219 	char		opFwLabel[32];
220 
221 	uint32_t	sli1FwRev;
222 	char		sli1FwName[32];
223 	char		sli1FwLabel[32];
224 
225 	uint32_t	sli2FwRev;
226 	char		sli2FwName[32];
227 	char		sli2FwLabel[32];
228 
229 	uint32_t	sli3FwRev;
230 	char		sli3FwName[32];
231 	char		sli3FwLabel[32];
232 
233 	uint32_t	sli4FwRev;
234 	char		sli4FwName[32];
235 	char		sli4FwLabel[32];
236 
237 	char		fw_version[32];
238 	char		fw_label[32];
239 
240 	char		fcode_version[32];
241 	char		boot_version[32];
242 
243 	char		serial_num[32];
244 	char		part_num[32];
245 	char		port_num[20];
246 	char		eng_change[32];
247 	char		manufacturer[80];
248 	char		model[80];
249 	char		model_desc[256];
250 	char		prog_types[256];
251 	char		id[80];
252 
253 	uint32_t	port_index;
254 	uint8_t		link_speed;
255 } emlxs_vpd_t;
256 
257 
258 typedef struct emlxs_queue
259 {
260 	uint8_t		*q_first;	/* queue first element */
261 	uint8_t		*q_last;	/* queue last element */
262 	uint16_t	q_cnt;	/* current length of queue */
263 	uint16_t	q_max;	/* max length queue can get */
264 } emlxs_queue_t;
265 typedef emlxs_queue_t Q;
266 
267 
268 
269 /*
270  * This structure is used when allocating a buffer pool.
271  * Note: this should be identical to gasket buf_info (fldl.h).
272  */
273 typedef struct emlxs_buf_info
274 {
275 	int32_t		size;	/* Specifies the number of bytes to allocate. */
276 	int32_t		align;	/* The desired address boundary. */
277 
278 	int32_t		flags;
279 
280 #define	FC_MBUF_DMA		0x01	/* blocks are for DMA */
281 #define	FC_MBUF_PHYSONLY	0x02	/* For malloc - map a given virtual */
282 					/* address to physical address (skip */
283 					/* the malloc). */
284 					/* For free - just unmap the given */
285 					/* physical address (skip the free). */
286 #define	FC_MBUF_IOCTL		0x04	/* called from dfc_ioctl */
287 #define	FC_MBUF_UNLOCK		0x08	/* called with driver unlocked */
288 #define	FC_MBUF_SNGLSG		0x10	/* allocate a single contiguous */
289 					/* physical memory */
290 #define	FC_MBUF_DMA32		0x20
291 
292 	uint64_t	phys;		/* specifies physical buffer pointer */
293 	void		*virt;		/* specifies virtual buffer pointer */
294 	void		*data_handle;
295 	void		*dma_handle;
296 } emlxs_buf_info_t;
297 typedef emlxs_buf_info_t MBUF_INFO;
298 
299 
300 #define	EMLXS_MAX_HBQ   	16	/* Max HBQs handled by firmware */
301 #define	EMLXS_ELS_HBQ_ID	0
302 #define	EMLXS_IP_HBQ_ID		1
303 #define	EMLXS_CT_HBQ_ID		2
304 #define	EMLXS_FCT_HBQ_ID	3
305 
306 #ifdef SFCT_SUPPORT
307 #define	EMLXS_NUM_HBQ		4	/* Number of HBQs supported by driver */
308 #else
309 #define	EMLXS_NUM_HBQ		3	/* Number of HBQs supported by driver */
310 #endif /* SFCT_SUPPORT */
311 
312 
313 /*
314  * An IO Channel is a object that comprises a xmit/cmpl
315  * path for IOs.
316  * For SLI3, an IO path maps to a ring (cmd/rsp)
317  * For SLI4, an IO path map to a queue pair (WQ/CQ)
318  */
319 typedef struct emlxs_channel
320 {
321 	struct emlxs_hba *hba;			/* ptr to hba for channel */
322 	void		*iopath;		/* ptr to SLI3/4 io path */
323 
324 	kmutex_t	rsp_lock;
325 	IOCBQ		*rsp_head;	/* deferred completion head */
326 	IOCBQ		*rsp_tail;	/* deferred completion tail */
327 	emlxs_thread_t  intr_thread;
328 
329 
330 	uint16_t	channelno;
331 	uint16_t	chan_flag;
332 
333 #define	EMLXS_NEEDS_TRIGGER 1
334 
335 	/* Protected by EMLXS_TX_CHANNEL_LOCK */
336 	emlxs_queue_t	nodeq;			/* Node service queue */
337 
338 	kmutex_t	channel_cmd_lock;
339 	uint32_t	timeout;
340 
341 	/* Channel command counters */
342 	uint32_t	ulpSendCmd;
343 	uint32_t	ulpCmplCmd;
344 	uint32_t	hbaSendCmd;
345 	uint32_t	hbaCmplCmd;
346 	uint32_t	hbaSendCmd_sbp;
347 	uint32_t	hbaCmplCmd_sbp;
348 
349 } emlxs_channel_t;
350 typedef emlxs_channel_t CHANNEL;
351 
352 /*
353  * Should be able to handle max number of io paths for a
354  * SLI4 HBA (EMLXS_MAX_WQS) or for a SLI3 HBA (MAX_RINGS)
355  */
356 #define	MAX_CHANNEL EMLXS_MSI_MAX_INTRS
357 
358 
359 /* Structure used to access adapter rings */
360 typedef struct emlxs_ring
361 {
362 	void		*fc_cmdringaddr;	/* virtual offset for cmd */
363 						/* rings */
364 	void		*fc_rspringaddr;	/* virtual offset for rsp */
365 						/* rings */
366 
367 	uint8_t		*fc_mpon;		/* index ptr for match */
368 						/* structure */
369 	uint8_t		*fc_mpoff;		/* index ptr for match */
370 						/* structure */
371 	struct emlxs_hba *hba;			/* ptr to hba for ring */
372 
373 	uint8_t		fc_numCiocb;		/* number of command iocb's */
374 						/* per ring */
375 	uint8_t		fc_numRiocb;		/* number of response iocb's */
376 						/* per ring */
377 	uint8_t		fc_rspidx;		/* current index in response */
378 						/* ring */
379 	uint8_t		fc_cmdidx;		/* current index in command */
380 						/* ring */
381 	uint8_t		fc_port_rspidx;
382 	uint8_t		fc_port_cmdidx;
383 	uint8_t		ringno;
384 
385 	uint16_t	fc_missbufcnt;		/* buf cnt we need to repost */
386 	CHANNEL		*channelp;
387 
388 
389 } emlxs_ring_t;
390 typedef emlxs_ring_t RING;
391 
392 
393 #ifdef SAN_DIAG_SUPPORT
394 /*
395  * Although right now it's just 1 field, SAN Diag anticipates that this
396  * structure will grow in the future.
397  */
398 typedef struct sd_timestat_level0 {
399 	int		count;
400 } sd_timestat_level0_t;
401 #endif
402 
403 typedef struct emlxs_node
404 {
405 	struct emlxs_node	*nlp_list_next;
406 	struct emlxs_node	*nlp_list_prev;
407 
408 	NAME_TYPE		nlp_portname;	/* port name */
409 	NAME_TYPE		nlp_nodename;	/* node name */
410 
411 	uint32_t		nlp_DID;	/* fibre channel D_ID */
412 	uint32_t		nlp_oldDID;
413 
414 	uint16_t		nlp_Rpi;	/* login id returned by */
415 						/* REG_LOGIN */
416 	uint16_t		nlp_Xri;	/* login id returned by */
417 						/* REG_LOGIN */
418 
419 	uint8_t			nlp_fcp_info;	/* Remote class info */
420 
421 	/* nlp_fcp_info */
422 #define	NLP_FCP_TGT_DEVICE	0x10	/* FCP TGT device */
423 #define	NLP_FCP_INI_DEVICE	0x20	/* FCP Initiator device */
424 #define	NLP_FCP_2_DEVICE	0x40	/* FCP-2 TGT device */
425 #define	NLP_EMLX_VPORT		0x80    /* Virtual port */
426 
427 	uint32_t		nlp_force_rscn;
428 	uint32_t		nlp_tag;	/* Tag used by port_offline */
429 	uint32_t		flag;
430 
431 #define	NODE_POOL_ALLOCATED 	0x00000001
432 
433 	SERV_PARM		sparm;
434 
435 	/* Protected by EMLXS_TX_CHANNEL_LOCK */
436 	uint32_t		nlp_active;	/* Node active flag */
437 	uint32_t		nlp_base;
438 	uint32_t		nlp_flag[MAX_CHANNEL];	/* Node level channel */
439 							/* flags */
440 
441 	/* nlp_flag */
442 #define	NLP_CLOSED		0x1
443 #define	NLP_OFFLINE		0x2
444 #define	NLP_RPI_XRI		0x4
445 
446 	uint32_t		nlp_tics[MAX_CHANNEL];	/* gate timeout */
447 	emlxs_queue_t		nlp_tx[MAX_CHANNEL];	/* Transmit Q head */
448 	emlxs_queue_t		nlp_ptx[MAX_CHANNEL];	/* Priority transmit */
449 							/* Queue head */
450 	void			*nlp_next[MAX_CHANNEL];	/* Service Request */
451 							/* Queue pointer used */
452 							/* when node needs */
453 							/* servicing */
454 #ifdef DHCHAP_SUPPORT
455 	emlxs_node_dhc_t	node_dhc;
456 #endif	/* DHCHAP_SUPPORT */
457 
458 #ifdef SAN_DIAG_SUPPORT
459 	sd_timestat_level0_t	sd_dev_bucket[SD_IO_LATENCY_MAX_BUCKETS];
460 #endif
461 
462 	struct RPIobject	*RPIp;	/* SLI4 only */
463 #define	EMLXS_NODE_TO_RPI(_h, _n)	\
464 	((_n)?((_n->RPIp)?_n->RPIp:emlxs_sli4_find_rpi(_h, _n->nlp_Rpi)):NULL)
465 
466 } emlxs_node_t;
467 typedef emlxs_node_t NODELIST;
468 
469 
470 
471 #define	NADDR_LEN	6	/* MAC network address length */
472 typedef struct emlxs_fcip_nethdr
473 {
474 	NAME_TYPE	fc_destname;	/* destination port name */
475 	NAME_TYPE	fc_srcname;	/* source port name */
476 } emlxs_fcip_nethdr_t;
477 typedef emlxs_fcip_nethdr_t NETHDR;
478 
479 
480 #define	MEM_NLP		0	/* memory segment to hold node list entries */
481 #define	MEM_IOCB	1	/* memory segment to hold iocb commands */
482 #define	MEM_MBOX	2	/* memory segment to hold mailbox cmds  */
483 #define	MEM_BPL		3	/* and to hold buffer ptr lists - SLI2   */
484 #define	MEM_BUF		4	/* memory segment to hold buffer data   */
485 #define	MEM_ELSBUF	4	/* memory segment to hold buffer data   */
486 #define	MEM_IPBUF	5	/* memory segment to hold IP buffer data */
487 #define	MEM_CTBUF	6	/* memory segment to hold CT buffer data */
488 #define	MEM_FCTBUF	7	/* memory segment to hold FCT buffer data */
489 
490 #ifdef SFCT_SUPPORT
491 #define	FC_MAX_SEG	8
492 #else
493 #define	FC_MAX_SEG	7
494 #endif /* SFCT_SUPPORT */
495 
496 
497 /* A BPL entry is 12 bytes. Subtract 2 for command and response buffers */
498 #define	BPL_TO_SGLLEN(_bpl)   ((_bpl/12)-2)
499 #define	MEM_BPL_SIZE		1024  /* Default size */
500 
501 /* A SGL entry is 16 bytes. Subtract 2 for command and response buffers */
502 #define	SGL_TO_SGLLEN(_sgl)   ((_sgl/16)-2)
503 #define	MEM_SGL_SIZE		1024  /* Default size */
504 
505 #ifdef EMLXS_I386
506 #define	EMLXS_SGLLEN		BPL_TO_SGLLEN(MEM_BPL_SIZE)
507 #else	/* EMLXS_SPARC */
508 #define	EMLXS_SGLLEN		1
509 #endif	/* EMLXS_I386 */
510 
511 #define	MEM_BUF_SIZE		1024
512 #define	MEM_BUF_COUNT		64
513 
514 #define	MEM_ELSBUF_SIZE   	MEM_BUF_SIZE
515 #define	MEM_ELSBUF_COUNT  	hba->max_nodes
516 #define	MEM_IPBUF_SIZE  	65535
517 #define	MEM_IPBUF_COUNT		60
518 #define	MEM_CTBUF_SIZE		MAX_CT_PAYLOAD	/* (1024*320) */
519 #define	MEM_CTBUF_COUNT		8
520 #define	MEM_FCTBUF_SIZE  	65535
521 #define	MEM_FCTBUF_COUNT	128
522 
523 typedef struct emlxs_memseg
524 {
525 	uint8_t			*fc_memget_ptr;
526 	uint8_t			*fc_memget_end;
527 	uint8_t			*fc_memput_ptr;
528 	uint8_t			*fc_memput_end;
529 
530 	uint8_t			*fc_memstart_virt;	/* beginning address */
531 							/* of memory block */
532 	uint64_t		fc_memstart_phys;	/* beginning address */
533 							/* of memory block */
534 	ddi_dma_handle_t	fc_mem_dma_handle;
535 	ddi_acc_handle_t	fc_mem_dat_handle;
536 	uint32_t		fc_total_memsize;
537 	uint32_t		fc_memsize;		/* size of mem blks */
538 	uint32_t		fc_numblks;		/* no of mem blks */
539 	uint32_t		fc_memget_cnt;		/* no of mem get blks */
540 	uint32_t		fc_memput_cnt;		/* no of mem put blks */
541 	uint32_t		fc_memflag;  /* emlxs_buf_info_t FLAGS */
542 	uint32_t		fc_reserved; /* used with priority flag */
543 	uint32_t		fc_memalign;
544 	uint32_t		fc_memtag;
545 	char			fc_label[32];
546 
547 } emlxs_memseg_t;
548 typedef emlxs_memseg_t MEMSEG;
549 
550 
551 /* Board stat counters */
552 typedef struct emlxs_stats
553 {
554 	uint32_t	LinkUp;
555 	uint32_t	LinkDown;
556 	uint32_t	LinkEvent;
557 	uint32_t	LinkMultiEvent;
558 
559 	uint32_t	MboxIssued;
560 	uint32_t	MboxCompleted;	/* MboxError + MbxGood */
561 	uint32_t	MboxGood;
562 	uint32_t	MboxError;
563 	uint32_t	MboxBusy;
564 	uint32_t	MboxInvalid;
565 
566 	uint32_t	IocbIssued[MAX_CHANNEL];
567 	uint32_t	IocbReceived[MAX_CHANNEL];
568 	uint32_t	IocbTxPut[MAX_CHANNEL];
569 	uint32_t	IocbTxGet[MAX_CHANNEL];
570 	uint32_t	IocbRingFull[MAX_CHANNEL];
571 	uint32_t	IocbThrottled;
572 
573 	uint32_t	IntrEvent[8];
574 
575 	uint32_t	FcpIssued;
576 	uint32_t	FcpCompleted;	/* FcpGood + FcpError */
577 	uint32_t	FcpGood;
578 	uint32_t	FcpError;
579 
580 	uint32_t	FcpEvent;	/* FcpStray + FcpCompleted */
581 	uint32_t	FcpStray;
582 #ifdef SFCT_SUPPORT
583 	uint32_t	FctRingEvent;
584 	uint32_t	FctRingError;
585 	uint32_t	FctRingDropped;
586 #endif /* SFCT_SUPPORT */
587 
588 	uint32_t	ElsEvent;	/* ElsStray + ElsCmplt (cmd + rsp) */
589 	uint32_t	ElsStray;
590 
591 	uint32_t	ElsCmdIssued;
592 	uint32_t	ElsCmdCompleted;	/* ElsCmdGood + ElsCmdError */
593 	uint32_t	ElsCmdGood;
594 	uint32_t	ElsCmdError;
595 
596 	uint32_t	ElsRspIssued;
597 	uint32_t	ElsRspCompleted;
598 
599 	uint32_t	ElsRcvEvent;	/* ElsRcvErr + ElsRcvDrop + ElsCmdRcv */
600 	uint32_t	ElsRcvError;
601 	uint32_t	ElsRcvDropped;
602 	uint32_t	ElsCmdReceived;	/* ElsRscnRcv + ElsPlogiRcv + ... */
603 	uint32_t	ElsRscnReceived;
604 	uint32_t	ElsFlogiReceived;
605 	uint32_t	ElsPlogiReceived;
606 	uint32_t	ElsPrliReceived;
607 	uint32_t	ElsPrloReceived;
608 	uint32_t	ElsLogoReceived;
609 	uint32_t	ElsAdiscReceived;
610 	uint32_t	ElsAuthReceived;
611 	uint32_t	ElsGenReceived;
612 
613 	uint32_t	CtEvent;	/* CtStray + CtCompleted (cmd + rsp) */
614 	uint32_t	CtStray;
615 
616 	uint32_t	CtCmdIssued;
617 	uint32_t	CtCmdCompleted;	/* CtCmdGood + CtCmdError */
618 	uint32_t	CtCmdGood;
619 	uint32_t	CtCmdError;
620 
621 	uint32_t	CtRspIssued;
622 	uint32_t	CtRspCompleted;
623 
624 	uint32_t	CtRcvEvent;	/* CtRcvError + CtRcvDrop + CtCmdRcvd */
625 	uint32_t	CtRcvError;
626 	uint32_t	CtRcvDropped;
627 	uint32_t	CtCmdReceived;
628 
629 	uint32_t	IpEvent;	/* IpStray + IpSeqCmpl + IpBcastCmpl */
630 	uint32_t	IpStray;
631 
632 	uint32_t	IpSeqIssued;
633 	uint32_t	IpSeqCompleted;	/* IpSeqGood + IpSeqError */
634 	uint32_t	IpSeqGood;
635 	uint32_t	IpSeqError;
636 
637 	uint32_t	IpBcastIssued;
638 	uint32_t	IpBcastCompleted;	/* IpBcastGood + IpBcastError */
639 	uint32_t	IpBcastGood;
640 	uint32_t	IpBcastError;
641 
642 	uint32_t	IpRcvEvent;	/* IpDrop + IpSeqRcv + IpBcastRcv */
643 	uint32_t	IpDropped;
644 	uint32_t	IpSeqReceived;
645 	uint32_t	IpBcastReceived;
646 
647 	uint32_t	IpUbPosted;
648 	uint32_t	ElsUbPosted;
649 	uint32_t	CtUbPosted;
650 #ifdef SFCT_SUPPORT
651 	uint32_t	FctUbPosted;
652 #endif /* SFCT_SUPPORT */
653 
654 	uint32_t	ResetTime;	/* Time of last reset */
655 } emlxs_stats_t;
656 
657 
658 #define	FC_MAX_ADPTMSG   (8*28)	/* max size of a msg from adapter */
659 
660 #define	EMLXS_NUM_THREADS	8
661 #define	EMLXS_MIN_TASKS		8
662 #define	EMLXS_MAX_TASKS		8
663 
664 #define	EMLXS_NUM_HASH_QUES	32
665 #define	EMLXS_DID_HASH(x)	((x) & (EMLXS_NUM_HASH_QUES - 1))
666 
667 
668 /* pkt_tran_flag */
669 #define	FC_TRAN_COMPLETED	0x8000
670 
671 
672 typedef struct emlxs_dfc_event
673 {
674 	uint32_t	pid;
675 	uint32_t	event;
676 	uint32_t	last_id;
677 
678 	void		*dataout;
679 	uint32_t	size;
680 	uint32_t	mode;
681 } emlxs_dfc_event_t;
682 
683 
684 typedef struct emlxs_hba_event
685 {
686 	uint32_t	last_id;
687 	uint32_t	new;
688 	uint32_t	missed;
689 } emlxs_hba_event_t;
690 
691 
692 #ifdef SFCT_SUPPORT
693 
694 #define	TGTPORTSTAT			port->fct_stat
695 
696 /*
697  * FctP2IOXcnt will count IOs by their fcpDL. Counters
698  * are for buckets of various power of 2 sizes.
699  * Bucket 0  <  512  > 0
700  * Bucket 1  >= 512  < 1024
701  * Bucket 2  >= 1024 < 2048
702  * Bucket 3  >= 2048 < 4096
703  * Bucket 4  >= 4096 < 8192
704  * Bucket 5  >= 8192 < 16K
705  * Bucket 6  >= 16K  < 32K
706  * Bucket 7  >= 32K  < 64K
707  * Bucket 8  >= 64K  < 128K
708  * Bucket 9  >= 128K < 256K
709  * Bucket 10 >= 256K < 512K
710  * Bucket 11 >= 512K < 1MB
711  * Bucket 12 >= 1MB  < 2MB
712  * Bucket 13 >= 2MB  < 4MB
713  * Bucket 14 >= 4MB  < 8MB
714  * Bucket 15 >= 8MB
715  */
716 #define	MAX_TGTPORT_IOCNT  16
717 
718 
719 /*
720  * These routines will bump the right counter, based on
721  * the size of the IO inputed, with the least number of
722  * comparisions.  A max of 5 comparisions is only needed
723  * to classify the IO in one of 16 ranges. A binary search
724  * to locate the high bit in the size is used.
725  */
726 #define	EMLXS_BUMP_RDIOCTR(port, cnt) \
727 { \
728 	/* Use binary search to find the first high bit */ \
729 	if (cnt & 0xffff0000) { \
730 		if (cnt & 0xff800000) { \
731 			TGTPORTSTAT.FctP2IORcnt[15]++; \
732 		} \
733 		else { \
734 			/* It must be 0x007f0000 */ \
735 			if (cnt & 0x00700000) { \
736 				if (cnt & 0x00400000) { \
737 					TGTPORTSTAT.FctP2IORcnt[14]++; \
738 				} \
739 				else { \
740 					/* it must be 0x00300000 */ \
741 					if (cnt & 0x00200000) { \
742 						TGTPORTSTAT.FctP2IORcnt[13]++; \
743 					} \
744 					else { \
745 						/* It must be 0x00100000 */ \
746 						TGTPORTSTAT.FctP2IORcnt[12]++; \
747 					} \
748 				} \
749 			} \
750 			else { \
751 				/* It must be 0x000f0000 */ \
752 				if (cnt & 0x000c0000) {	\
753 					if (cnt & 0x00080000) {	\
754 						TGTPORTSTAT.FctP2IORcnt[11]++; \
755 					} \
756 					else { \
757 						/* It must be 0x00040000 */ \
758 						TGTPORTSTAT.FctP2IORcnt[10]++; \
759 					} \
760 				} \
761 				else { \
762 					/* It must be 0x00030000 */ \
763 					if (cnt & 0x00020000) {	\
764 						TGTPORTSTAT.FctP2IORcnt[9]++; \
765 					} \
766 					else { \
767 						/* It must be 0x00010000 */ \
768 						TGTPORTSTAT.FctP2IORcnt[8]++; \
769 					} \
770 				} \
771 			} \
772 		} \
773 	} \
774 	else { \
775 		if (cnt & 0x0000fe00) { \
776 			if (cnt & 0x0000f000) { \
777 				if (cnt & 0x0000c000) { \
778 					if (cnt & 0x00008000) { \
779 						TGTPORTSTAT.FctP2IORcnt[7]++; \
780 					} \
781 					else { \
782 						/* It must be 0x00004000 */ \
783 						TGTPORTSTAT.FctP2IORcnt[6]++; \
784 					} \
785 				} \
786 				else { \
787 					/* It must be 0x00000300 */ \
788 					if (cnt & 0x00000200) { \
789 						TGTPORTSTAT.FctP2IORcnt[5]++; \
790 					} \
791 					else { \
792 						/* It must be 0x00000100 */ \
793 						TGTPORTSTAT.FctP2IORcnt[4]++; \
794 					} \
795 				} \
796 			} \
797 			else { \
798 				/* It must be 0x00000e00 */ \
799 				if (cnt & 0x00000800) { \
800 					TGTPORTSTAT.FctP2IORcnt[3]++; \
801 				} \
802 				else { \
803 					/* It must be 0x00000600 */ \
804 					if (cnt & 0x00000400) { \
805 						TGTPORTSTAT.FctP2IORcnt[2]++; \
806 					} \
807 					else { \
808 						/* It must be 0x00000200 */ \
809 						TGTPORTSTAT.FctP2IORcnt[1]++; \
810 					} \
811 				} \
812 			} \
813 		} \
814 		else { \
815 			/* It must be 0x000001ff */ \
816 			TGTPORTSTAT.FctP2IORcnt[0]++; \
817 		} \
818 	} \
819 }
820 
821 
822 #define	EMLXS_BUMP_WRIOCTR(port, cnt) \
823 { \
824 /* Use binary search to find the first high bit */ \
825 	if (cnt & 0xffff0000) { \
826 		if (cnt & 0xff800000) { \
827 			TGTPORTSTAT.FctP2IOWcnt[15]++; \
828 		} \
829 		else { \
830 			/* It must be 0x007f0000 */ \
831 			if (cnt & 0x00700000) { \
832 				if (cnt & 0x00400000) { \
833 					TGTPORTSTAT.FctP2IOWcnt[14]++; \
834 				} \
835 				else { \
836 					/* It must be 0x00300000 */ \
837 					if (cnt & 0x00200000) { \
838 						TGTPORTSTAT.FctP2IOWcnt[13]++; \
839 					} \
840 					else { \
841 						/* It must be 0x00100000 */ \
842 						TGTPORTSTAT.FctP2IOWcnt[12]++; \
843 					} \
844 				} \
845 			} \
846 			else { \
847 				/* It must be 0x000f0000 */ \
848 				if (cnt & 0x000c0000) { \
849 					if (cnt & 0x00080000) { \
850 						TGTPORTSTAT.FctP2IOWcnt[11]++; \
851 					} \
852 					else { \
853 						/* it must be 0x00040000 */ \
854 						TGTPORTSTAT.FctP2IOWcnt[10]++; \
855 					} \
856 				} \
857 				else { \
858 					/* It must be 0x00030000 */ \
859 					if (cnt & 0x00020000) { \
860 						TGTPORTSTAT.FctP2IOWcnt[9]++; \
861 					} \
862 					else { \
863 						/* It must be 0x00010000 */ \
864 						TGTPORTSTAT.FctP2IOWcnt[8]++; \
865 					} \
866 				} \
867 			} \
868 		} \
869 	} \
870 	else { \
871 		if (cnt & 0x0000fe00) { \
872 			if (cnt & 0x0000f000) { \
873 				if (cnt & 0x0000c000) { \
874 					if (cnt & 0x00008000) { \
875 						TGTPORTSTAT.FctP2IOWcnt[7]++; \
876 					} \
877 					else { \
878 						/* It must be 0x00004000 */ \
879 						TGTPORTSTAT.FctP2IOWcnt[6]++; \
880 					} \
881 				} \
882 				else { \
883 					/* It must be 0x00000300 */ \
884 					if (cnt & 0x00000200) { \
885 						TGTPORTSTAT.FctP2IOWcnt[5]++; \
886 					} \
887 					else { \
888 						/* It must be 0x00000100 */ \
889 						TGTPORTSTAT.FctP2IOWcnt[4]++; \
890 					} \
891 				} \
892 			} \
893 			else { \
894 				/* It must be 0x00000e00 */ \
895 				if (cnt & 0x00000800) { \
896 					TGTPORTSTAT.FctP2IOWcnt[3]++; \
897 				} \
898 				else { \
899 					/* It must be 0x00000600 */ \
900 					if (cnt & 0x00000400) { \
901 						TGTPORTSTAT.FctP2IOWcnt[2]++; \
902 					} \
903 					else { \
904 						/* It must be 0x00000200 */ \
905 						TGTPORTSTAT.FctP2IOWcnt[1]++; \
906 					} \
907 				} \
908 			} \
909 		} \
910 		else { \
911 			/* It must be 0x000001ff */ \
912 			TGTPORTSTAT.FctP2IOWcnt[0]++; \
913 		} \
914 	} \
915 }
916 
917 typedef struct emlxs_tgtport_stat
918 {
919 	/* IO counters */
920 	uint64_t	FctP2IOWcnt[MAX_TGTPORT_IOCNT]; /* Writes */
921 	uint64_t	FctP2IORcnt[MAX_TGTPORT_IOCNT]; /* Reads  */
922 	uint64_t	FctIOCmdCnt;			/* Other, ie TUR */
923 	uint64_t	FctCmdReceived;			/* total IOs */
924 	uint64_t	FctReadBytes;			/* total read bytes */
925 	uint64_t	FctWriteBytes;			/* total write bytes */
926 
927 	/* IOCB handling counters */
928 	uint64_t	FctEvent;	/* FctStray + FctCompleted */
929 	uint64_t	FctCompleted;	/* FctCmplGood + FctCmplError */
930 	uint64_t	FctCmplGood;
931 
932 	uint32_t	FctCmplError;
933 	uint32_t	FctStray;
934 
935 	/* Fct event counters */
936 	uint32_t	FctRcvDropped;
937 	uint32_t	FctOverQDepth;
938 	uint32_t	FctOutstandingIO;
939 	uint32_t	FctFailedPortRegister;
940 	uint32_t	FctPortRegister;
941 	uint32_t	FctPortDeregister;
942 
943 	uint32_t	FctAbortSent;
944 	uint32_t	FctNoBuffer;
945 	uint32_t	FctScsiStatusErr;
946 	uint32_t	FctScsiQfullErr;
947 	uint32_t	FctScsiResidOver;
948 	uint32_t	FctScsiResidUnder;
949 	uint32_t	FctScsiSenseErr;
950 
951 	uint32_t	FctFiller1;
952 } emlxs_tgtport_stat_t;
953 
954 #ifdef FCT_IO_TRACE
955 #define	MAX_IO_TRACE	67
956 typedef struct emlxs_iotrace
957 {
958 	fct_cmd_t	*fct_cmd;
959 	uint32_t	xri;
960 	uint8_t		marker;  /* 0xff */
961 	uint8_t		trc[MAX_IO_TRACE]; /* trc[0] = index */
962 } emlxs_iotrace_t;
963 #endif /* FCT_IO_TRACE */
964 #endif /* SFCT_SUPPORT */
965 
966 
967 /*
968  *     Port Information Data Structure
969  */
970 
971 typedef struct emlxs_port
972 {
973 	struct emlxs_hba	*hba;
974 
975 	/* Virtual port management */
976 	uint32_t		vpi;
977 	uint32_t		flag;
978 #define	EMLXS_PORT_ENABLE		0x00000001
979 #define	EMLXS_PORT_BOUND		0x00000002
980 
981 #define	EMLXS_PORT_REGISTERED		0x00010000	/* VPI registered */
982 #define	EMLXS_PORT_INIT_VPI_CMPL	0x00020000	/* Init VPI - SLI4 */
983 #define	EMLXS_PORT_REG_VPI_CMPL		0x00040000	/* Reg VPI - SLI4 */
984 #define	EMLXS_PORT_IP_UP		0x00000010
985 #define	EMLXS_PORT_CONFIG		0x00000020
986 #define	EMLXS_PORT_RESTRICTED		0x00000040	/* Restrict logins */
987 							/* flag */
988 #define	EMLXS_PORT_FLOGI_CMPL		0x00000080	/* Fabric login */
989 							/* completed */
990 
991 #define	EMLXS_PORT_RESET_MASK		0x0000FFFF	/* Flags to keep */
992 							/* across hard reset */
993 #define	EMLXS_PORT_LINKDOWN_MASK	0xFFFFFFFF	/* Flags to keep */
994 							/* across link reset */
995 
996 	uint32_t		options;
997 #define	EMLXS_OPT_RESTRICT		0x00000001	/* Force restricted */
998 							/* logins */
999 #define	EMLXS_OPT_UNRESTRICT		0x00000002	/* Force Unrestricted */
1000 							/* logins */
1001 #define	EMLXS_OPT_RESTRICT_MASK		0x00000003
1002 
1003 
1004 	/* FC world wide names */
1005 	NAME_TYPE		wwnn;
1006 	NAME_TYPE		wwpn;
1007 	char			snn[256];
1008 	char			spn[256];
1009 
1010 	/* Common service paramters */
1011 	SERV_PARM		sparam;
1012 	SERV_PARM		fabric_sparam;
1013 
1014 	/* fc_id management */
1015 	uint32_t		did;
1016 	uint32_t		prev_did;
1017 
1018 	/* support FC_PORT_GET_P2P_INFO only */
1019 	uint32_t		rdid;
1020 
1021 	/* FC_AL management */
1022 	uint8_t			lip_type;
1023 	uint8_t			alpa_map[128];
1024 
1025 	/* Node management */
1026 	emlxs_node_t		node_base;
1027 	uint32_t		node_count;
1028 	krwlock_t		node_rwlock;
1029 	emlxs_node_t		*node_table[EMLXS_NUM_HASH_QUES];
1030 
1031 	/* Polled packet management */
1032 	kcondvar_t		pkt_lock_cv;	/* pkt polling */
1033 	kmutex_t		pkt_lock;	/* pkt polling */
1034 
1035 	/* ULP */
1036 	uint32_t		ulp_statec;
1037 	void			(*ulp_statec_cb) ();	/* Port state change */
1038 							/* callback routine */
1039 	void			(*ulp_unsol_cb) ();	/* unsolicited event */
1040 							/* callback routine */
1041 	opaque_t		ulp_handle;
1042 
1043 	/* ULP unsolicited buffers */
1044 	kmutex_t		ub_lock;
1045 	uint32_t		ub_count;
1046 	emlxs_unsol_buf_t	*ub_pool;
1047 	uint32_t		ub_post[MAX_CHANNEL];
1048 	uint32_t		ub_timer;
1049 
1050 	emlxs_ub_priv_t		*ub_wait_head;	/* Unsolicited IO received */
1051 						/* before link up */
1052 	emlxs_ub_priv_t		*ub_wait_tail;	/* Unsolicited IO received */
1053 						/* before link up */
1054 
1055 
1056 #ifdef DHCHAP_SUPPORT
1057 	emlxs_port_dhc_t	port_dhc;
1058 #endif	/* DHCHAP_SUPPORT */
1059 
1060 	uint16_t		ini_mode;
1061 	uint16_t		tgt_mode;
1062 
1063 #ifdef SFCT_SUPPORT
1064 
1065 #define	FCT_BUF_COUNT_512		256
1066 #define	FCT_BUF_COUNT_8K		128
1067 #define	FCT_BUF_COUNT_64K		64
1068 #define	FCT_BUF_COUNT_128K		64
1069 #define	FCT_MAX_BUCKETS			16
1070 #define	FCT_DMEM_MAX_BUF_SIZE		131072   /* 128K */
1071 #define	FCT_DMEM_MAX_BUF_SEGMENT	8388608  /* 8M */
1072 
1073 	struct emlxs_fct_dmem_bucket dmem_bucket[FCT_MAX_BUCKETS];
1074 	int			fct_queue_depth;
1075 #define	EMLXS_FCT_DFLT_QDEPTH   64
1076 
1077 	char			cfd_name[24];
1078 	stmf_port_provider_t	*port_provider;
1079 	fct_local_port_t	*fct_port;
1080 	uint32_t		fct_flags;
1081 
1082 #define	FCT_STATE_PORT_ONLINE		0x00000001
1083 #define	FCT_STATE_NOT_ACKED		0x00000002
1084 #define	FCT_STATE_LINK_UP		0x00000010
1085 #define	FCT_STATE_LINK_UP_ACKED		0x00000020
1086 
1087 	emlxs_tgtport_stat_t	fct_stat;
1088 
1089 	/* Used to save fct_cmd for deferred unsol ELS commands, except FLOGI */
1090 	emlxs_buf_t		*fct_wait_head;
1091 	emlxs_buf_t		*fct_wait_tail;
1092 
1093 	/* Used to save context for deferred unsol FLOGIs */
1094 	fct_flogi_xchg_t	fx;
1095 
1096 #ifdef FCT_IO_TRACE
1097 	emlxs_iotrace_t		*iotrace;
1098 	uint16_t		iotrace_cnt;
1099 	uint16_t		iotrace_index;
1100 	kmutex_t		iotrace_mtx;
1101 #endif /* FCT_IO_TRACE */
1102 
1103 #endif /* SFCT_SUPPORT */
1104 
1105 #ifdef SAN_DIAG_SUPPORT
1106 	uint8_t			sd_io_latency_state;
1107 #define	SD_INVALID	0x00
1108 #define	SD_COLLECTING	0x01
1109 #define	SD_STOPPED	0x02
1110 
1111 	/* SD event management list */
1112 	uint32_t		sd_event_mask;   /* bit-mask */
1113 	emlxs_dfc_event_t	sd_events[MAX_DFC_EVENTS];
1114 #endif
1115 	/* Used for SLI4 */
1116 	uint16_t	outstandingRPIs;
1117 	struct VFIobject *VFIp;
1118 } emlxs_port_t;
1119 
1120 
1121 
1122 /* Host Attn reg */
1123 #define	FC_HA_REG(_hba)		((volatile uint32_t *) \
1124 				    ((_hba)->sli.sli3.ha_reg_addr))
1125 
1126 /* Chip Attn reg */
1127 #define	FC_CA_REG(_hba)		((volatile uint32_t *) \
1128 				    ((_hba)->sli.sli3.ca_reg_addr))
1129 
1130 /* Host Status reg */
1131 #define	FC_HS_REG(_hba)		((volatile uint32_t *) \
1132 				    ((_hba)->sli.sli3.hs_reg_addr))
1133 
1134 /* Host Cntl reg */
1135 #define	FC_HC_REG(_hba)		((volatile uint32_t *) \
1136 				    ((_hba)->sli.sli3.hc_reg_addr))
1137 
1138 /* BIU Configuration reg */
1139 #define	FC_BC_REG(_hba)		((volatile uint32_t *) \
1140 				    ((_hba)->sli.sli3.bc_reg_addr))
1141 
1142 /* Used by SBUS adapter */
1143 /* TITAN Cntl reg */
1144 #define	FC_SHC_REG(_hba)	((volatile uint32_t *) \
1145 				    ((_hba)->sli.sli3.shc_reg_addr))
1146 
1147 /* TITAN Status reg */
1148 #define	FC_SHS_REG(_hba)	((volatile uint32_t *) \
1149 				    ((_hba)->sli.sli3.shs_reg_addr))
1150 
1151 /* TITAN Update reg */
1152 #define	FC_SHU_REG(_hba)	((volatile uint32_t *) \
1153 				    ((_hba)->sli.sli3.shu_reg_addr))
1154 
1155 /* MPU Semaphore reg */
1156 #define	FC_SEMA_REG(_hba)	((volatile uint32_t *)\
1157 				    ((_hba)->sli.sli4.MPUEPSemaphore_reg_addr))
1158 
1159 /* Bootstrap Mailbox Doorbell reg */
1160 #define	FC_MBDB_REG(_hba)	((volatile uint32_t *) \
1161 				    ((_hba)->sli.sli4.MBDB_reg_addr))
1162 
1163 /* MQ Doorbell reg */
1164 #define	FC_MQDB_REG(_hba)	((volatile uint32_t *) \
1165 				    ((_hba)->sli.sli4.MQDB_reg_addr))
1166 
1167 /* CQ Doorbell reg */
1168 #define	FC_CQDB_REG(_hba)	((volatile uint32_t *) \
1169 				    ((_hba)->sli.sli4.CQDB_reg_addr))
1170 
1171 /* WQ Doorbell reg */
1172 #define	FC_WQDB_REG(_hba)	((volatile uint32_t *) \
1173 				    ((_hba)->sli.sli4.WQDB_reg_addr))
1174 
1175 /* RQ Doorbell reg */
1176 #define	FC_RQDB_REG(_hba)	((volatile uint32_t *) \
1177 				    ((_hba)->sli.sli4.RQDB_reg_addr))
1178 
1179 
1180 #define	FC_SLIM2_MAILBOX(_hba)	((MAILBOX *)(_hba)->sli.sli3.slim2.virt)
1181 
1182 #define	FC_SLIM1_MAILBOX(_hba)	((MAILBOX *)(_hba)->sli.sli3.slim_addr)
1183 
1184 #define	FC_MAILBOX(_hba)	(((_hba)->flag & FC_SLIM2_MODE) ? \
1185 	FC_SLIM2_MAILBOX(_hba) : FC_SLIM1_MAILBOX(_hba))
1186 
1187 #define	WRITE_CSR_REG(_hba, _regp, _value) ddi_put32(\
1188 	(_hba)->sli.sli3.csr_acc_handle, (uint32_t *)(_regp), \
1189 	(uint32_t)(_value))
1190 
1191 #define	READ_CSR_REG(_hba, _regp) ddi_get32(\
1192 	(_hba)->sli.sli3.csr_acc_handle, (uint32_t *)(_regp))
1193 
1194 #define	WRITE_SLIM_ADDR(_hba, _regp, _value) ddi_put32(\
1195 	(_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_regp), \
1196 	(uint32_t)(_value))
1197 
1198 #define	READ_SLIM_ADDR(_hba, _regp) ddi_get32(\
1199 	(_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_regp))
1200 
1201 #define	WRITE_SLIM_COPY(_hba, _bufp, _slimp, _wcnt) ddi_rep_put32(\
1202 	(_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_bufp), \
1203 	(uint32_t *)(_slimp), (_wcnt), DDI_DEV_AUTOINCR)
1204 
1205 #define	READ_SLIM_COPY(_hba, _bufp, _slimp, _wcnt) ddi_rep_get32(\
1206 	(_hba)->sli.sli3.slim_acc_handle, (uint32_t *)(_bufp), \
1207 	(uint32_t *)(_slimp), (_wcnt), DDI_DEV_AUTOINCR)
1208 
1209 /* Used by SBUS adapter */
1210 #define	WRITE_SBUS_CSR_REG(_hba, _regp, _value)	ddi_put32(\
1211 	(_hba)->sli.sli3.sbus_csr_handle, (uint32_t *)(_regp), \
1212 	(uint32_t)(_value))
1213 
1214 #define	READ_SBUS_CSR_REG(_hba, _regp) ddi_get32(\
1215 	(_hba)->sli.sli3.sbus_csr_handle, (uint32_t *)(_regp))
1216 
1217 #define	SBUS_WRITE_FLASH_COPY(_hba, _offset, _value) ddi_put8(\
1218 	(_hba)->sli.sli3.sbus_flash_acc_handle, \
1219 	(uint8_t *)((volatile uint8_t *)(_hba)->sli.sli3.sbus_flash_addr + \
1220 	(_offset)), (uint8_t)(_value))
1221 
1222 #define	SBUS_READ_FLASH_COPY(_hba, _offset) ddi_get8(\
1223 	(_hba)->sli.sli3.sbus_flash_acc_handle, \
1224 	(uint8_t *)((volatile uint8_t *)(_hba)->sli.sli3.sbus_flash_addr + \
1225 	(_offset)))
1226 
1227 /* SLI4 registers */
1228 #define	WRITE_BAR1_REG(_hba, _regp, _value) ddi_put32(\
1229 	(_hba)->sli.sli4.bar1_acc_handle, (uint32_t *)(_regp), \
1230 	(uint32_t)(_value))
1231 
1232 #define	READ_BAR1_REG(_hba, _regp) ddi_get32(\
1233 	(_hba)->sli.sli4.bar1_acc_handle, (uint32_t *)(_regp))
1234 
1235 #define	WRITE_BAR2_REG(_hba, _regp, _value) ddi_put32(\
1236 	(_hba)->sli.sli4.bar2_acc_handle, (uint32_t *)(_regp), \
1237 	(uint32_t)(_value))
1238 
1239 #define	READ_BAR2_REG(_hba, _regp) ddi_get32(\
1240 	(_hba)->sli.sli4.bar2_acc_handle, (uint32_t *)(_regp))
1241 
1242 
1243 #define	EMLXS_STATE_CHANGE(_hba, _state)\
1244 {									\
1245 	mutex_enter(&EMLXS_PORT_LOCK);					\
1246 	EMLXS_STATE_CHANGE_LOCKED((_hba), (_state));			\
1247 	mutex_exit(&EMLXS_PORT_LOCK);					\
1248 }
1249 
1250 /* Used when EMLXS_PORT_LOCK is already held */
1251 #define	EMLXS_STATE_CHANGE_LOCKED(_hba, _state)			\
1252 {									\
1253 	if ((_hba)->state != (_state))					\
1254 	{								\
1255 		uint32_t _st = _state;					\
1256 		EMLXS_MSGF(EMLXS_CONTEXT,				\
1257 			&emlxs_state_msg, "%s --> %s",			\
1258 			emlxs_ffstate_xlate((_hba)->state),		\
1259 			emlxs_ffstate_xlate(_state));			\
1260 			(_hba)->state = (_state);			\
1261 		if ((_st) == FC_ERROR)					\
1262 		{							\
1263 			(_hba)->flag |= FC_HARDWARE_ERROR;		\
1264 		}							\
1265 	}								\
1266 }
1267 
1268 #ifdef FMA_SUPPORT
1269 #define	EMLXS_CHK_ACC_HANDLE(_hba, _acc) \
1270 	if (emlxs_fm_check_acc_handle(_hba, _acc) != DDI_FM_OK) { \
1271 		EMLXS_MSGF(EMLXS_CONTEXT, \
1272 		    &emlxs_invalid_access_handle_msg, NULL); \
1273 	}
1274 #endif  /* FMA_SUPPORT */
1275 
1276 /*
1277  * This is the HBA control area for the adapter
1278  */
1279 
1280 #ifdef MODSYM_SUPPORT
1281 
1282 typedef struct emlxs_modsym
1283 {
1284 	ddi_modhandle_t  mod_fctl;	/* For Leadville */
1285 
1286 	/* Leadville (fctl) */
1287 	int		(*fc_fca_attach)(dev_info_t *, fc_fca_tran_t *);
1288 	int		(*fc_fca_detach)(dev_info_t *);
1289 	int		(*fc_fca_init)(struct dev_ops *);
1290 
1291 #ifdef SFCT_SUPPORT
1292 	uint32_t	fct_modopen;
1293 	uint32_t	reserved;  /* Padding for alignment */
1294 
1295 	ddi_modhandle_t  mod_fct;	/* For Comstar */
1296 	ddi_modhandle_t  mod_stmf;	/* For Comstar */
1297 
1298 	/* Comstar (fct) */
1299 	void*	(*fct_alloc)(fct_struct_id_t, int, int);
1300 	void	(*fct_free)(void *);
1301 	void*	(*fct_scsi_task_alloc)(void *, uint16_t, uint32_t, uint8_t *,
1302 			uint16_t, uint16_t);
1303 	int	(*fct_register_local_port)(fct_local_port_t *);
1304 	void	(*fct_deregister_local_port)(fct_local_port_t *);
1305 	void	(*fct_handle_event)(fct_local_port_t *, int, uint32_t, caddr_t);
1306 	void	(*fct_post_rcvd_cmd)(fct_cmd_t *, stmf_data_buf_t *);
1307 	void	(*fct_ctl)(void *, int, void *);
1308 	void	(*fct_queue_cmd_for_termination)(fct_cmd_t *, fct_status_t);
1309 	void	(*fct_send_response_done)(fct_cmd_t *, fct_status_t, uint32_t);
1310 	void	(*fct_send_cmd_done)(fct_cmd_t *, fct_status_t, uint32_t);
1311 	void	(*fct_scsi_data_xfer_done)(fct_cmd_t *, stmf_data_buf_t *,
1312 			uint32_t);
1313 	fct_status_t	(*fct_port_shutdown)
1314 				(fct_local_port_t *, uint32_t, char *);
1315 	fct_status_t	(*fct_port_initialize)
1316 				(fct_local_port_t *, uint32_t, char *);
1317 	void		(*fct_cmd_fca_aborted)
1318 				(fct_cmd_t *, fct_status_t, int);
1319 	fct_status_t	(*fct_handle_rcvd_flogi)
1320 				(fct_local_port_t *, fct_flogi_xchg_t *);
1321 
1322 	/* Comstar (stmf) */
1323 	void*  (*stmf_alloc)(stmf_struct_id_t, int, int);
1324 	void   (*stmf_free)(void *);
1325 	void	(*stmf_deregister_port_provider) (stmf_port_provider_t *);
1326 	int	(*stmf_register_port_provider) (stmf_port_provider_t *);
1327 #endif /* SFCT_SUPPORT */
1328 } emlxs_modsym_t;
1329 extern emlxs_modsym_t emlxs_modsym;
1330 
1331 #define	MODSYM(_f)	emlxs_modsym._f
1332 
1333 #else
1334 
1335 #define	MODSYM(_f)	_f
1336 
1337 #endif /* MODSYM_SUPPORT */
1338 
1339 
1340 
1341 /* defines for resource state */
1342 #define	RESOURCE_FREE		0
1343 #define	RESOURCE_ALLOCATED	1
1344 
1345 #define	RESOURCE_FCFI_REG	2
1346 #define	RESOURCE_FCFI_DISC	4
1347 #define	RESOURCE_FCFI_VLAN_ID	8
1348 
1349 #define	RESOURCE_VFI_REG	2
1350 
1351 #define	RESOURCE_RPI_PAUSED	2
1352 
1353 #define	RESOURCE_XRI_RESERVED		2
1354 #define	RESOURCE_XRI_PENDING_IO		4
1355 #define	RESOURCE_XRI_ABORT_INP		8
1356 
1357 typedef struct VFIobject
1358 {
1359 	uint16_t	index;
1360 	uint16_t	VFI;
1361 	uint16_t	state;
1362 	uint16_t	outstandingVPIs;
1363 	struct FCFIobject *FCFIp;
1364 } VFIobj_t;
1365 
1366 typedef struct RPIobject
1367 {
1368 	uint16_t	index;
1369 	uint16_t	RPI;
1370 	uint16_t	state;
1371 	uint16_t	outstandingXRIs;
1372 	emlxs_port_t	*VPIp;
1373 	uint32_t	did;
1374 	emlxs_node_t	*node;
1375 } RPIobj_t;
1376 
1377 typedef struct XRIobject
1378 {
1379 	struct XRIobject *_f;
1380 	struct XRIobject *_b;
1381 	uint16_t	XRI;
1382 	uint16_t	state;
1383 	uint16_t	sge_count;
1384 	uint16_t	iotag;
1385 	MBUF_INFO	SGList;
1386 	RPIobj_t	*RPIp;
1387 	emlxs_buf_t	*sbp;
1388 	uint32_t 	rx_id; /* Used for unsol exchanges */
1389 } XRIobj_t;
1390 
1391 typedef struct FCFIobject
1392 {
1393 	uint16_t	index;
1394 	uint16_t	FCFI;
1395 	uint16_t	FCF_index;
1396 	uint16_t	state;
1397 	uint16_t	outstandingVFIs;
1398 	uint16_t	vlan_id;
1399 	uint32_t	EventTag;
1400 	struct VFIobject *fcf_vfi;
1401 	emlxs_port_t	*fcf_vpi;
1402 	struct RPIobject scratch_rpi;
1403 	SERV_PARM	fcf_sparam;
1404 	FCF_RECORD_t	fcf_rec;
1405 } FCFIobj_t;
1406 
1407 typedef struct RPIHdrTmplate
1408 {
1409 	uint32_t	Word[16];  /* 64 bytes */
1410 } RPIHdrTmplate_t;
1411 
1412 typedef struct EQ_DESC
1413 {
1414 	uint16_t	host_index;
1415 	uint16_t	max_index;
1416 	uint16_t	qid;
1417 	uint16_t	msix_vector;
1418 	kmutex_t	lastwq_lock;
1419 	uint16_t	lastwq;
1420 	MBUF_INFO	addr;
1421 } EQ_DESC_t;
1422 
1423 typedef struct CQ_DESC
1424 {
1425 	uint16_t	host_index;
1426 	uint16_t	max_index;
1427 	uint16_t	qid;
1428 	uint16_t	eqid;
1429 	uint16_t	type;
1430 #define	EMLXS_CQ_TYPE_GROUP1	1  /* associated with a MQ and async events */
1431 #define	EMLXS_CQ_TYPE_GROUP2	2  /* associated with a WQ and RQ */
1432 	uint16_t	rsvd;
1433 
1434 	MBUF_INFO	addr;
1435 	CHANNEL		*channelp; /* ptr to CHANNEL associated with CQ */
1436 
1437 } CQ_DESC_t;
1438 
1439 typedef struct WQ_DESC
1440 {
1441 	uint16_t	host_index;
1442 	uint16_t	max_index;
1443 	uint16_t	port_index;
1444 	uint16_t	release_depth;
1445 #define	WQE_RELEASE_DEPTH	(8 * EMLXS_NUM_WQ_PAGES)
1446 	uint16_t	qid;
1447 	uint16_t	cqid;
1448 	MBUF_INFO	addr;
1449 } WQ_DESC_t;
1450 
1451 typedef struct RQ_DESC
1452 {
1453 	uint16_t	host_index;
1454 	uint16_t	max_index;
1455 	uint16_t	qid;
1456 	uint16_t	cqid;
1457 
1458 	MBUF_INFO	addr;
1459 	MEMSEG		rqb_pool;
1460 	MATCHMAP	*rqb[RQ_DEPTH];
1461 
1462 	kmutex_t	lock;
1463 
1464 } RQ_DESC_t;
1465 
1466 
1467 typedef struct RXQ_DESC
1468 {
1469 	kmutex_t	lock;
1470 	emlxs_queue_t	active;
1471 
1472 } RXQ_DESC_t;
1473 
1474 
1475 typedef struct MQ_DESC
1476 {
1477 	uint16_t	host_index;
1478 	uint16_t	max_index;
1479 	uint16_t	qid;
1480 	uint16_t	cqid;
1481 	MBUF_INFO	addr;
1482 } MQ_DESC_t;
1483 
1484 /* Define the number of queues the driver will be using */
1485 #define	EMLXS_MAX_EQS	EMLXS_MSI_MAX_INTRS
1486 #define	EMLXS_MAX_WQS	EMLXS_MSI_MAX_INTRS
1487 #define	EMLXS_MAX_RQS	2	/* ONLY 1 pair is allowed */
1488 #define	EMLXS_MAX_MQS	1
1489 
1490 /* One CQ for each WQ & (RQ pair) plus one for the MQ */
1491 #define	EMLXS_MAX_CQS	(EMLXS_MAX_WQS + (EMLXS_MAX_RQS/2) + 1)
1492 
1493 /* The First CQ created is ALWAYS for mbox / event handling */
1494 #define	EMLXS_CQ_MBOX		0
1495 
1496 /* The Second CQ created is ALWAYS for unsol rcv handling */
1497 /* At this time we are allowing ONLY 1 pair of RQs */
1498 #define	EMLXS_CQ_RCV		1
1499 
1500 /* The remaining CQs are for WQ completions */
1501 #define	EMLXS_CQ_OFFSET_WQ	2
1502 
1503 
1504 /* FCFI RQ Configuration */
1505 #define	EMLXS_FCFI_RQ0_INDEX	0
1506 #define	EMLXS_FCFI_RQ0_RMASK	0 /* match all */
1507 #define	EMLXS_FCFI_RQ0_RCTL	0 /* match all */
1508 #define	EMLXS_FCFI_RQ0_TMASK	0 /* match all */
1509 #define	EMLXS_FCFI_RQ0_TYPE	0 /* match all */
1510 
1511 /* Define the maximum value for a Queue Id */
1512 #define	EMLXS_MAX_EQ_IDS	256
1513 #define	EMLXS_MAX_CQ_IDS	1024
1514 #define	EMLXS_MAX_WQ_IDS	1024
1515 #define	EMLXS_MAX_RQ_IDS	4
1516 
1517 #define	EMLXS_RXQ_ELS		0
1518 #define	EMLXS_RXQ_CT		1
1519 #define	EMLXS_MAX_RXQS		2
1520 
1521 #define	PCI_CONFIG_SIZE   0x80
1522 
1523 typedef struct emlxs_sli3
1524 {
1525 	/* SLIM management */
1526 	MATCHMAP	slim2;
1527 
1528 	/* HBQ management */
1529 	uint32_t	hbq_count;	/* Total number of HBQs */
1530 					/* configured */
1531 	HBQ_INIT_t	hbq_table[EMLXS_NUM_HBQ];
1532 
1533 	/* Adapter memory management */
1534 	caddr_t		csr_addr;
1535 	caddr_t		slim_addr;
1536 	ddi_acc_handle_t csr_acc_handle;
1537 	ddi_acc_handle_t slim_acc_handle;
1538 
1539 	/* SBUS adapter management */
1540 	caddr_t		sbus_flash_addr;	/* Virt addr of R/W */
1541 						/* Flash */
1542 	caddr_t		sbus_core_addr;		/* Virt addr of TITAN */
1543 						/* CORE */
1544 	caddr_t		sbus_csr_addr;		/* Virt addr of TITAN */
1545 						/* CSR */
1546 	ddi_acc_handle_t sbus_flash_acc_handle;
1547 	ddi_acc_handle_t sbus_core_acc_handle;
1548 	ddi_acc_handle_t sbus_csr_handle;
1549 
1550 	/* SLI 2/3 Adapter register management */
1551 	uint32_t	*bc_reg_addr;	/* virtual offset for BIU */
1552 					/* config reg */
1553 	uint32_t	*ha_reg_addr;	/* virtual offset for host */
1554 					/* attn reg */
1555 	uint32_t	*hc_reg_addr;	/* virtual offset for host */
1556 					/* ctl reg */
1557 	uint32_t	*ca_reg_addr;	/* virtual offset for FF */
1558 					/* attn reg */
1559 	uint32_t	*hs_reg_addr;	/* virtual offset for */
1560 					/* status reg */
1561 	uint32_t	*shc_reg_addr;	/* virtual offset for SBUS */
1562 					/* Ctrl reg */
1563 	uint32_t	*shs_reg_addr;	/* virtual offset for SBUS */
1564 					/* Status reg */
1565 	uint32_t	*shu_reg_addr;	/* virtual offset for SBUS */
1566 					/* Update reg */
1567 	uint16_t	hgp_ring_offset;
1568 	uint16_t	hgp_hbq_offset;
1569 	uint16_t	iocb_cmd_size;
1570 	uint16_t	iocb_rsp_size;
1571 	uint32_t	hc_copy;	/* local copy of HC register */
1572 
1573 	/* Ring management */
1574 	uint32_t	ring_count;
1575 	emlxs_ring_t	ring[MAX_RINGS];
1576 	kmutex_t	ring_cmd_lock[MAX_RINGS];
1577 	uint8_t		ring_masks[4];	/* number of masks/rings used */
1578 	uint8_t		ring_rval[6];
1579 	uint8_t		ring_rmask[6];
1580 	uint8_t		ring_tval[6];
1581 	uint8_t		ring_tmask[6];
1582 
1583 	/* Protected by EMLXS_FCTAB_LOCK */
1584 #ifdef EMLXS_SPARC
1585 	MEMSEG		fcp_bpl_seg;
1586 	MATCHMAP	**fcp_bpl_table; /* iotag table for */
1587 					/* bpl buffers */
1588 #endif	/* EMLXS_SPARC */
1589 	uint32_t	mem_bpl_size;
1590 } emlxs_sli3_t;
1591 
1592 typedef struct emlxs_sli4
1593 {
1594 	MATCHMAP	bootstrapmb;
1595 	caddr_t		bar1_addr;
1596 	caddr_t		bar2_addr;
1597 	ddi_acc_handle_t bar1_acc_handle;
1598 	ddi_acc_handle_t bar2_acc_handle;
1599 
1600 	/* SLI4 Adapter register management */
1601 	uint32_t	*MPUEPSemaphore_reg_addr;
1602 	uint32_t	*MBDB_reg_addr;
1603 
1604 	uint32_t	*CQDB_reg_addr;
1605 	uint32_t	*MQDB_reg_addr;
1606 	uint32_t	*WQDB_reg_addr;
1607 	uint32_t	*RQDB_reg_addr;
1608 
1609 	uint32_t	flag;
1610 #define	EMLXS_SLI4_INTR_ENABLED		0x1
1611 
1612 	uint16_t	XRICount;
1613 	uint16_t	XRIBase;
1614 	uint16_t	RPICount;
1615 	uint16_t	RPIBase;
1616 	uint16_t	VPICount;
1617 	uint16_t	VPIBase;
1618 	uint16_t	VFICount;
1619 	uint16_t	VFIBase;
1620 	uint16_t	FCFICount;
1621 
1622 	kmutex_t	id_lock; /* for FCFI, VFI, VPI, RPI, XRI mgmt */
1623 	FCFIobj_t	*FCFIp;
1624 	VFIobj_t	*VFIp;
1625 
1626 	/* Save Config Region 23 info */
1627 	tlv_fcoe_t	cfgFCOE;
1628 	tlv_fcfconnectlist_t	cfgFCF;
1629 
1630 	MBUF_INFO	dump_region;
1631 #define	EMLXS_DUMP_REGION_SIZE	1024
1632 
1633 	RPIobj_t	*RPIp;
1634 	MBUF_INFO	HeaderTmplate;
1635 	XRIobj_t	*XRIp;
1636 	/* Single linked list for available XRIs */
1637 	XRIobj_t	*XRIfree_list;
1638 	XRIobj_t	*XRIfree_tail;
1639 	uint32_t	xrif_count;
1640 	uint32_t	mem_sgl_size;
1641 
1642 	/* Double linked list for XRIs in use */
1643 	XRIobj_t	*XRIinuse_f;
1644 	XRIobj_t	*XRIinuse_b;
1645 	uint32_t	xria_count;
1646 
1647 	EQ_DESC_t	eq[EMLXS_MAX_EQS];
1648 	CQ_DESC_t	cq[EMLXS_MAX_CQS];
1649 	WQ_DESC_t	wq[EMLXS_MAX_WQS];
1650 	RQ_DESC_t	rq[EMLXS_MAX_RQS];
1651 	MQ_DESC_t	mq;
1652 
1653 	/* Used to map a queue ID to a queue DESC_t */
1654 	uint16_t	eq_map[EMLXS_MAX_EQ_IDS];
1655 	uint16_t	cq_map[EMLXS_MAX_CQ_IDS];
1656 	uint16_t	wq_map[EMLXS_MAX_WQ_IDS];
1657 	uint16_t	rq_map[EMLXS_MAX_RQ_IDS];
1658 
1659 	RXQ_DESC_t	rxq[EMLXS_MAX_RXQS];
1660 
1661 	uint32_t	ue_mask_lo;
1662 	uint32_t	ue_mask_hi;
1663 } emlxs_sli4_t;
1664 
1665 
1666 typedef struct emlxs_sli_api
1667 {
1668 	int		(*sli_map_hdw)();
1669 	void		(*sli_unmap_hdw)();
1670 	int32_t		(*sli_online)();
1671 	void		(*sli_offline)();
1672 	uint32_t	(*sli_hba_reset)();
1673 	void		(*sli_hba_kill)();
1674 	void		(*sli_issue_iocb_cmd)();
1675 	uint32_t	(*sli_issue_mbox_cmd)();
1676 	uint32_t	(*sli_prep_fct_iocb)();
1677 	uint32_t	(*sli_prep_fcp_iocb)();
1678 	uint32_t	(*sli_prep_ip_iocb)();
1679 	uint32_t	(*sli_prep_els_iocb)();
1680 	uint32_t	(*sli_prep_ct_iocb)();
1681 	void		(*sli_poll_intr)();
1682 	int32_t		(*sli_intx_intr)();
1683 	uint32_t	(*sli_msi_intr)();
1684 	void		(*sli_disable_intr)();
1685 	void		(*sli_timer)();
1686 	void		(*sli_poll_erratt)();
1687 
1688 } emlxs_sli_api_t;
1689 
1690 
1691 typedef struct emlxs_hba
1692 {
1693 	dev_info_t	*dip;
1694 	int32_t		emlxinst;
1695 	int32_t		ddiinst;
1696 	uint8_t		pci_function_number;
1697 	uint8_t		pci_device_number;
1698 	uint8_t		pci_bus_number;
1699 #ifdef FMA_SUPPORT
1700 	int32_t		fm_caps;	/* FMA capabilities */
1701 #endif	/* FMA_SUPPORT */
1702 	fc_fca_tran_t	*fca_tran;
1703 
1704 	/* HBA Info */
1705 	emlxs_model_t	model_info;
1706 	emlxs_vpd_t	vpd;	/* vital product data */
1707 	NAME_TYPE	wwnn;
1708 	NAME_TYPE	wwpn;
1709 	char		snn[256];
1710 	char		spn[256];
1711 	PROG_ID		load_list[MAX_LOAD_ENTRY];
1712 	WAKE_UP_PARMS	wakeup_parms;
1713 	uint32_t	max_nodes;
1714 	uint32_t	io_throttle;
1715 	uint32_t	io_active;
1716 	uint32_t	bus_type;
1717 #define	PCI_FC  	0
1718 #define	SBUS_FC		1
1719 
1720 	/* Link management */
1721 	uint32_t	link_event_tag;
1722 	uint8_t		topology;
1723 	uint8_t		linkspeed;
1724 	uint32_t	linkup_wait_flag;
1725 	kcondvar_t	linkup_lock_cv;
1726 	kmutex_t	linkup_lock;
1727 
1728 	/* Memory Pool management */
1729 	emlxs_memseg_t	memseg[FC_MAX_SEG];	/* memory for buffer */
1730 							/* structures */
1731 	kmutex_t	memget_lock;	/* locks all memory pools get */
1732 	kmutex_t	memput_lock;	/* locks all memory pools put */
1733 
1734 	/* Fibre Channel Service Parameters */
1735 	SERV_PARM	sparam;
1736 	uint32_t	fc_edtov;	/* E_D_TOV timer value */
1737 	uint32_t	fc_arbtov;	/* ARB_TOV timer value */
1738 	uint32_t	fc_ratov;	/* R_A_TOV timer value */
1739 	uint32_t	fc_rttov;	/* R_T_TOV timer value */
1740 	uint32_t	fc_altov;	/* AL_TOV timer value */
1741 	uint32_t	fc_crtov;	/* C_R_TOV timer value */
1742 	uint32_t	fc_citov;	/* C_I_TOV timer value */
1743 
1744 	/* Adapter State management */
1745 	int32_t		state;
1746 #define	FC_ERROR		0x01	/* Adapter shutdown */
1747 #define	FC_KILLED		0x02	/* Adapter interlocked/killed */
1748 #define	FC_WARM_START		0x03	/* Adapter reset, but not restarted */
1749 #define	FC_INIT_START		0x10	/* Adapter restarted */
1750 #define	FC_INIT_NVPARAMS	0x11
1751 #define	FC_INIT_REV		0x12
1752 #define	FC_INIT_CFGPORT		0x13
1753 #define	FC_INIT_CFGRING		0x14
1754 #define	FC_INIT_INITLINK	0x15
1755 #define	FC_LINK_DOWN		0x20
1756 #define	FC_LINK_DOWN_PERSIST	0x21
1757 #define	FC_LINK_UP		0x30
1758 #define	FC_CLEAR_LA		0x31
1759 #define	FC_READY		0x40
1760 
1761 	uint32_t	flag;
1762 #define	FC_ONLINING_MODE	0x00000001
1763 #define	FC_ONLINE_MODE		0x00000002
1764 #define	FC_OFFLINING_MODE	0x00000004
1765 #define	FC_OFFLINE_MODE		0x00000008
1766 
1767 #define	FC_NPIV_ENABLED		0x00000010	/* NPIV enabled on adapter    */
1768 #define	FC_NPIV_SUPPORTED	0x00000020	/* NPIV supported on fabric   */
1769 #define	FC_NPIV_UNSUPPORTED	0x00000040	/* NPIV unsupported on fabric */
1770 #define	FC_NPIV_LINKUP		0x00000100	/* NPIV enabled, supported, */
1771 						/* and link is ready */
1772 #define	FC_NPIV_DELAY_REQUIRED	0x00000200	/* Delay issuing FLOGI/FDISC */
1773 						/* and NameServer cmds */
1774 
1775 #define	FC_BOOTSTRAPMB_INIT	0x00000400
1776 #define	FC_FIP_SUPPORTED	0x00000800	/* FIP supported */
1777 
1778 #define	FC_FABRIC_ATTACHED	0x00001000
1779 #define	FC_PT_TO_PT		0x00002000
1780 #define	FC_BYPASSED_MODE	0x00004000
1781 #define	FC_MENLO_MODE		0x00008000	/* Menlo maintenance mode */
1782 
1783 #define	FC_DUMP_SAFE		0x00010000	/* Safe to DUMP */
1784 #define	FC_DUMP_ACTIVE		0x00020000	/* DUMP in progress */
1785 
1786 #define	FC_SLIM2_MODE		0x00100000	/* SLIM in host memory */
1787 #define	FC_INTERLOCKED		0x00200000
1788 #define	FC_HBQ_ENABLED		0x00400000
1789 #define	FC_ASYNC_EVENTS		0x00800000
1790 
1791 #define	FC_ILB_MODE		0x01000000
1792 #define	FC_ELB_MODE		0x02000000
1793 #define	FC_LOOPBACK_MODE	0x03000000	/* Loopback Mode Mask */
1794 #define	FC_DUMP			0x04000000	/* DUMP in progress */
1795 #define	FC_SHUTDOWN		0x08000000	/* SHUTDOWN in progress */
1796 
1797 #define	FC_OVERTEMP_EVENT	0x10000000	/* FC_ERROR reason: */
1798 						/* over temperature event */
1799 #define	FC_MBOX_TIMEOUT		0x20000000	/* FC_ERROR reason: */
1800 						/* mailbox timeout event */
1801 #define	FC_HARDWARE_ERROR	0x80000000	/* FC_ERROR state triggered */
1802 
1803 #define	FC_RESET_MASK		0x00030C1F	/* Bits to protect during */
1804 						/* a hard reset */
1805 #define	FC_LINKDOWN_MASK	0xFFF30C1F	/* Bits to protect during */
1806 						/* a linkdown */
1807 
1808 	uint32_t temperature;			/* Last reported temperature */
1809 
1810 	/* SBUS adapter management */
1811 	caddr_t		sbus_pci_addr;		/* Virt addr of TITAN */
1812 						/* pci config */
1813 	ddi_acc_handle_t sbus_pci_handle;
1814 
1815 	/* PCI BUS adapter management */
1816 	caddr_t		pci_addr;
1817 	ddi_acc_handle_t pci_acc_handle;
1818 
1819 	uint32_t	sli_mode;
1820 #define	EMLXS_HBA_SLI1_MODE	1
1821 #define	EMLXS_HBA_SLI2_MODE	2
1822 #define	EMLXS_HBA_SLI3_MODE	3
1823 #define	EMLXS_HBA_SLI4_MODE	4
1824 
1825 	/* SLI private data */
1826 	union {
1827 		emlxs_sli3_t sli3;
1828 		emlxs_sli4_t sli4;
1829 	} sli;
1830 
1831 	/* SLI API entry point routines */
1832 	emlxs_sli_api_t sli_api;
1833 
1834 	uint32_t	io_poll_count;	/* Number of poll commands */
1835 					/* in progress */
1836 
1837 	/* IO Completion management */
1838 	uint32_t	iodone_count;	/* Number of IO's on done Q */
1839 	/* Protected by EMLXS_PORT_LOCK  */
1840 	emlxs_buf_t	*iodone_list;	/* fc_packet being deferred */
1841 	emlxs_buf_t	*iodone_tail;	/* fc_packet being deferred */
1842 	emlxs_thread_t	iodone_thread;
1843 	emlxs_thread_t	*spawn_thread_head;
1844 	emlxs_thread_t	*spawn_thread_tail;
1845 	kmutex_t	spawn_lock;
1846 	uint32_t	spawn_open;
1847 
1848 	/* IO Channel management */
1849 	int32_t		chan_count;
1850 	emlxs_channel_t	chan[MAX_CHANNEL];
1851 	kmutex_t	channel_tx_lock;
1852 	uint8_t		channel_fcp;	/* Default channel to use for FCP IO */
1853 #define	CHANNEL_FCT channel_fcp
1854 	uint8_t		channel_ip;	/* Default channel to use for IP IO */
1855 	uint8_t		channel_els;	/* Default channel to use for ELS IO */
1856 	uint8_t		channel_ct;	/* Default channel to use for CT IO */
1857 
1858 	/* IOTag management */
1859 	emlxs_buf_t	**fc_table;	/* sc_buf pointers indexed by */
1860 					/* iotag */
1861 	uint16_t	fc_iotag;	/* used to identify I/Os */
1862 	uint16_t	fc_oor_iotag;	/* OutOfRange (fc_table) iotags */
1863 					/* typically used for Abort/close */
1864 #define	EMLXS_MAX_ABORT_TAG	0x7fff
1865 	uint16_t	max_iotag;	/* ALL IOCBs except aborts */
1866 	kmutex_t	iotag_lock;
1867 	uint32_t	io_count;		/* No of IO holding */
1868 						/* regular iotag */
1869 	uint32_t	channel_tx_count;	/* No of IO on tx Q */
1870 
1871 	/* Mailbox Management */
1872 	uint32_t	mbox_queue_flag;
1873 	emlxs_queue_t	mbox_queue;
1874 	uint32_t	*mbox_mqe;	/* active mbox mqe */
1875 	uint8_t		*mbox_mbq;	/* active MAILBOXQ */
1876 	kcondvar_t	mbox_lock_cv;	/* MBX_SLEEP */
1877 	kmutex_t	mbox_lock;	/* MBX_SLEEP */
1878 	uint32_t	mbox_timer;
1879 
1880 	/* Interrupt management */
1881 	void		*intr_arg;
1882 	uint32_t	intr_unclaimed;
1883 	uint32_t	intr_autoClear;
1884 	uint32_t	intr_flags;
1885 #define	EMLXS_INTX_INITED	0x0001
1886 #define	EMLXS_INTX_ADDED	0x0002
1887 #define	EMLXS_MSI_ENABLED	0x0010
1888 #define	EMLXS_MSI_INITED	0x0020
1889 #define	EMLXS_MSI_ADDED		0x0040
1890 #define	EMLXS_INTR_INITED	(EMLXS_INTX_INITED|EMLXS_MSI_INITED)
1891 #define	EMLXS_INTR_ADDED	(EMLXS_INTX_ADDED|EMLXS_MSI_ADDED)
1892 
1893 #ifdef MSI_SUPPORT
1894 	ddi_intr_handle_t *intr_htable;
1895 	uint32_t	*intr_pri;
1896 	int32_t		*intr_cap;
1897 	uint32_t	intr_count;
1898 	uint32_t	intr_type;
1899 	uint32_t	intr_cond;
1900 	uint32_t	intr_map[EMLXS_MSI_MAX_INTRS];
1901 	uint32_t	intr_mask;
1902 	uint32_t	msi_cap_offset;
1903 #define	MSI_CAP_ID	0x05
1904 
1905 	uint32_t	msix_cap_offset;
1906 #define	MSIX_CAP_ID	0x11
1907 
1908 	kmutex_t	intr_lock[EMLXS_MSI_MAX_INTRS];
1909 #endif	/* MSI_SUPPORT */
1910 
1911 	uint32_t	heartbeat_timer;
1912 	uint32_t	heartbeat_flag;
1913 	uint32_t	heartbeat_active;
1914 
1915 	/* IOCTL management */
1916 	kmutex_t	ioctl_lock;
1917 	uint32_t	ioctl_flags;
1918 #define	EMLXS_OPEN		0x00000001
1919 #define	EMLXS_OPEN_EXCLUSIVE	0x00000002
1920 
1921 	/* Timer management */
1922 	kcondvar_t	timer_lock_cv;
1923 	kmutex_t	timer_lock;
1924 	timeout_id_t	timer_id;
1925 	uint32_t	timer_tics;
1926 	uint32_t	timer_flags;
1927 #define	EMLXS_TIMER_STARTED	0x0000001
1928 #define	EMLXS_TIMER_BUSY	0x0000002
1929 #define	EMLXS_TIMER_KILL	0x0000004
1930 #define	EMLXS_TIMER_ENDED	0x0000008
1931 
1932 	/* Misc Timers */
1933 	uint32_t	linkup_timer;
1934 	uint32_t	discovery_timer;
1935 	uint32_t	pkt_timer;
1936 
1937 	/* Power Management */
1938 	uint32_t	pm_state;
1939 	/* pm_state */
1940 #define	EMLXS_PM_IN_ATTACH	0x00000001
1941 #define	EMLXS_PM_IN_DETACH	0x00000002
1942 #define	EMLXS_PM_IN_SOL_CB	0x00000010
1943 #define	EMLXS_PM_IN_UNSOL_CB	0x00000020
1944 #define	EMLXS_PM_IN_LINK_RESET	0x00000100
1945 #define	EMLXS_PM_IN_HARD_RESET	0x00000200
1946 #define	EMLXS_PM_SUSPENDED	0x01000000
1947 
1948 	uint32_t	pm_level;
1949 	/* pm_level */
1950 #define	EMLXS_PM_ADAPTER_DOWN	0
1951 #define	EMLXS_PM_ADAPTER_UP	1
1952 
1953 	uint32_t	pm_busy;
1954 	kmutex_t	pm_lock;
1955 	uint8_t		pm_config[PCI_CONFIG_SIZE];
1956 #ifdef IDLE_TIMER
1957 	uint32_t	pm_idle_timer;
1958 	uint32_t	pm_active;	/* Only used by timer */
1959 #endif	/* IDLE_TIMER */
1960 
1961 	/* Loopback management */
1962 	uint32_t	loopback_tics;
1963 	void		*loopback_pkt;
1964 
1965 	/* Event management */
1966 	emlxs_event_queue_t event_queue;
1967 	uint32_t	event_mask;
1968 	uint32_t	event_timer;
1969 	emlxs_dfc_event_t dfc_event[MAX_DFC_EVENTS];
1970 	emlxs_hba_event_t hba_event;
1971 
1972 	/* Parameter management */
1973 	emlxs_config_t	config[NUM_CFG_PARAM];
1974 
1975 	/* Driver stat management */
1976 	kstat_t		*kstat;
1977 	emlxs_stats_t	stats;
1978 
1979 	/* Log management */
1980 	emlxs_msg_log_t	log;
1981 
1982 	/* Port managment */
1983 	uint32_t	vpi_base;
1984 	uint32_t	vpi_max;
1985 	uint32_t	vpi_high;
1986 	uint32_t	num_of_ports;
1987 
1988 	kmutex_t	port_lock;	/* locks port, nodes, rings */
1989 	emlxs_port_t	port[MAX_VPORTS + 1];	/* port specific info */
1990 						/* Last one is for */
1991 						/* NPIV ready test */
1992 
1993 #ifdef DHCHAP_SUPPORT
1994 	kmutex_t	dhc_lock;
1995 	kmutex_t	auth_lock;
1996 	emlxs_auth_cfg_t	auth_cfg;	/* Default auth_cfg. */
1997 						/* Points to list of entries. */
1998 						/* Protected by auth_lock */
1999 	uint32_t	auth_cfg_count;
2000 	emlxs_auth_key_t	auth_key;	/* Default auth_key. */
2001 						/* Points to list of entries. */
2002 						/* Protected by auth_lock */
2003 	uint32_t	auth_key_count;
2004 	uint32_t	rdn_flag;
2005 #endif	/* DHCHAP_SUPPORT */
2006 
2007 	uint16_t	ini_mode;
2008 	uint16_t	tgt_mode;
2009 
2010 #ifdef TEST_SUPPORT
2011 	uint32_t	underrun_counter;
2012 #endif /* TEST_SUPPORT */
2013 
2014 #ifdef MODFW_SUPPORT
2015 	ddi_modhandle_t	fw_modhandle;
2016 #endif /* MODFW_SUPPORT */
2017 
2018 #ifdef DUMP_SUPPORT
2019 	emlxs_file_t	dump_txtfile;
2020 	emlxs_file_t	dump_dmpfile;
2021 	emlxs_file_t	dump_ceefile;
2022 	kmutex_t	dump_lock;
2023 #define	EMLXS_DUMP_LOCK		hba->dump_lock
2024 #define	EMLXS_TXT_FILE		1
2025 #define	EMLXS_DMP_FILE		2
2026 #define	EMLXS_CEE_FILE		3
2027 
2028 #define	EMLXS_DRV_DUMP		0
2029 #define	EMLXS_TEMP_DUMP		1
2030 #define	EMLXS_USER_DUMP		2
2031 
2032 #endif /* DUMP_SUPPORT */
2033 
2034 } emlxs_hba_t;
2035 
2036 #define	EMLXS_SLI_MAP_HDW 		(hba->sli_api.sli_map_hdw)
2037 #define	EMLXS_SLI_UNMAP_HDW		(hba->sli_api.sli_unmap_hdw)
2038 #define	EMLXS_SLI_ONLINE		(hba->sli_api.sli_online)
2039 #define	EMLXS_SLI_OFFLINE		(hba->sli_api.sli_offline)
2040 #define	EMLXS_SLI_HBA_RESET		(hba->sli_api.sli_hba_reset)
2041 #define	EMLXS_SLI_HBA_KILL		(hba->sli_api.sli_hba_kill)
2042 #define	EMLXS_SLI_ISSUE_IOCB_CMD	(hba->sli_api.sli_issue_iocb_cmd)
2043 #define	EMLXS_SLI_ISSUE_MBOX_CMD	(hba->sli_api.sli_issue_mbox_cmd)
2044 #define	EMLXS_SLI_PREP_FCT_IOCB		(hba->sli_api.sli_prep_fct_iocb)
2045 #define	EMLXS_SLI_PREP_FCP_IOCB		(hba->sli_api.sli_prep_fcp_iocb)
2046 #define	EMLXS_SLI_PREP_IP_IOCB		(hba->sli_api.sli_prep_ip_iocb)
2047 #define	EMLXS_SLI_PREP_ELS_IOCB		(hba->sli_api.sli_prep_els_iocb)
2048 #define	EMLXS_SLI_PREP_CT_IOCB		(hba->sli_api.sli_prep_ct_iocb)
2049 #define	EMLXS_SLI_POLL_INTR		(hba->sli_api.sli_poll_intr)
2050 #define	EMLXS_SLI_INTX_INTR		(hba->sli_api.sli_intx_intr)
2051 #define	EMLXS_SLI_MSI_INTR		(hba->sli_api.sli_msi_intr)
2052 #define	EMLXS_SLI_DISABLE_INTR		(hba->sli_api.sli_disable_intr)
2053 #define	EMLXS_SLI_TIMER			(hba->sli_api.sli_timer)
2054 #define	EMLXS_SLI_POLL_ERRATT		(hba->sli_api.sli_poll_erratt)
2055 
2056 #define	EMLXS_HBA_T  1  /* flag emlxs_hba_t is already typedefed */
2057 
2058 #ifdef MSI_SUPPORT
2059 #define	EMLXS_INTR_INIT(_hba, _m)		emlxs_msi_init(_hba, _m)
2060 #define	EMLXS_INTR_UNINIT(_hba)			emlxs_msi_uninit(_hba)
2061 #define	EMLXS_INTR_ADD(_hba)			emlxs_msi_add(_hba)
2062 #define	EMLXS_INTR_REMOVE(_hba)			emlxs_msi_remove(_hba)
2063 #else
2064 #define	EMLXS_INTR_INIT(_hba, _m)		emlxs_intx_init(_hba, _m)
2065 #define	EMLXS_INTR_UNINIT(_hba)			emlxs_intx_uninit(_hba)
2066 #define	EMLXS_INTR_ADD(_hba)			emlxs_intx_add(_hba)
2067 #define	EMLXS_INTR_REMOVE(_hba)			emlxs_intx_remove(_hba)
2068 #endif	/* MSI_SUPPORT */
2069 
2070 
2071 /* Power Management Component */
2072 #define	EMLXS_PM_ADAPTER	0
2073 
2074 
2075 #define	DRV_TIME	(uint32_t)(ddi_get_time() - emlxs_device.drv_timestamp)
2076 
2077 #define	HBA			port->hba
2078 #define	PPORT			hba->port[0]
2079 #define	VPORT(x)		hba->port[x]
2080 #define	EMLXS_TIMER_LOCK	hba->timer_lock
2081 #define	VPD			hba->vpd
2082 #define	CFG			hba->config[0]
2083 #define	LOG			hba->log
2084 #define	EVENTQ			hba->event_queue
2085 #define	EMLXS_MBOX_LOCK		hba->mbox_lock
2086 #define	EMLXS_MBOX_CV		hba->mbox_lock_cv
2087 #define	EMLXS_LINKUP_LOCK	hba->linkup_lock
2088 #define	EMLXS_LINKUP_CV		hba->linkup_lock_cv
2089 #define	EMLXS_TX_CHANNEL_LOCK	hba->channel_tx_lock	/* ring txq lock */
2090 #define	EMLXS_MEMGET_LOCK	hba->memget_lock	/* mempool get lock */
2091 #define	EMLXS_MEMPUT_LOCK	hba->memput_lock	/* mempool put lock */
2092 #define	EMLXS_IOCTL_LOCK	hba->ioctl_lock		/* ioctl lock */
2093 #define	HBASTATS		hba->stats
2094 #define	EMLXS_CMD_RING_LOCK(n)	hba->sli.sli3.ring_cmd_lock[n]
2095 #define	EMLXS_FCTAB_LOCK	hba->iotag_lock
2096 #define	EMLXS_PORT_LOCK		hba->port_lock		/* locks ports, */
2097 							/* nodes, rings */
2098 #define	EMLXS_INTR_LOCK(_id)	hba->intr_lock[_id]	/* locks intr threads */
2099 
2100 #define	EMLXS_PKT_LOCK		port->pkt_lock		/* used for pkt */
2101 							/* polling */
2102 #define	EMLXS_PKT_CV		port->pkt_lock_cv	/* Used for pkt */
2103 							/* polling */
2104 #define	EMLXS_UB_LOCK		port->ub_lock		/* locks unsolicited */
2105 							/* buffer pool */
2106 
2107 /* These SWAPs will swap on any platform */
2108 #define	SWAP32_BUFFER(_b, _c)		emlxs_swap32_buffer(_b, _c)
2109 #define	SWAP32_BCOPY(_s, _d, _c)	emlxs_swap32_bcopy(_s, _d, _c)
2110 
2111 #define	SWAP64(_x)	((((uint64_t)(_x) & 0xFF)<<56) | \
2112 			    (((uint64_t)(_x) & 0xFF00)<<40) | \
2113 			    (((uint64_t)(_x) & 0xFF0000)<<24) | \
2114 			    (((uint64_t)(_x) & 0xFF000000)<<8) | \
2115 			    (((uint64_t)(_x) & 0xFF00000000)>>8) | \
2116 			    (((uint64_t)(_x) & 0xFF0000000000)>>24) | \
2117 			    (((uint64_t)(_x) & 0xFF000000000000)>>40) | \
2118 			    (((uint64_t)(_x) & 0xFF00000000000000)>>56))
2119 
2120 #define	SWAP32(_x)	((((uint32_t)(_x) & 0xFF)<<24) | \
2121 			    (((uint32_t)(_x) & 0xFF00)<<8) | \
2122 			    (((uint32_t)(_x) & 0xFF0000)>>8) | \
2123 			    (((uint32_t)(_x) & 0xFF000000)>>24))
2124 
2125 #define	SWAP16(_x)	((((uint16_t)(_x) & 0xFF)<<8) | \
2126 			    (((uint16_t)(_x) & 0xFF00)>>8))
2127 
2128 #define	SWAP24_LO(_x)	((((uint32_t)(_x) & 0xFF)<<16) | \
2129 			    ((uint32_t)(_x) & 0xFF00FF00) | \
2130 			    (((uint32_t)(_x) & 0x00FF0000)>>16))
2131 
2132 #define	SWAP24_HI(_x)	(((uint32_t)(_x) & 0x00FF00FF) | \
2133 			    (((uint32_t)(_x) & 0x0000FF00)<<16) | \
2134 			    (((uint32_t)(_x) & 0xFF000000)>>16))
2135 
2136 /* These LE_SWAPs will only swap on a LE platform */
2137 #ifdef EMLXS_LITTLE_ENDIAN
2138 #define	LE_SWAP32_BUFFER(_b, _c)	SWAP32_BUFFER(_b, _c)
2139 #define	LE_SWAP32_BCOPY(_s, _d, _c)	SWAP32_BCOPY(_s, _d, _c)
2140 #define	LE_SWAP64(_x)			SWAP64(_x)
2141 #define	LE_SWAP32(_x)			SWAP32(_x)
2142 #define	LE_SWAP16(_x)			SWAP16(_x)
2143 #define	LE_SWAP24_LO(_x)		SWAP24_LO(X)
2144 #define	LE_SWAP24_HI(_x)		SWAP24_HI(X)
2145 
2146 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2147 #undef	LE_SWAP24_LO
2148 #define	LE_SWAP24_LO(_x)		(_x)
2149 #undef	LE_SWAP24_HI
2150 #define	LE_SWAP24_HI(_x)		(_x)
2151 #endif	/* EMLXS_MODREV2X */
2152 
2153 #else /* BIG ENDIAN */
2154 #define	LE_SWAP32_BUFFER(_b, _c)
2155 #define	LE_SWAP32_BCOPY(_s, _d, _c)	bcopy(_s, _d, _c)
2156 #define	LE_SWAP64(_x)			(_x)
2157 #define	LE_SWAP32(_x)			(_x)
2158 #define	LE_SWAP16(_x)			(_x)
2159 #define	LE_SWAP24_LO(_x)		(_x)
2160 #define	LE_SWAP24_HI(_x)		(_x)
2161 #endif /* EMLXS_LITTLE_ENDIAN */
2162 
2163 /* These BE_SWAPs will only swap on a BE platform */
2164 #ifdef EMLXS_BIG_ENDIAN
2165 #define	BE_SWAP32_BUFFER(_b, _c)	SWAP32_BUFFER(_b, _c)
2166 #define	BE_SWAP32_BCOPY(_s, _d, _c)	SWAP32_BCOPY(_s, _d, _c)
2167 #define	BE_SWAP64(_x)			SWAP64(_x)
2168 #define	BE_SWAP32(_x)			SWAP32(_x)
2169 #define	BE_SWAP16(_x)			SWAP16(_x)
2170 #else /* LITTLE ENDIAN */
2171 #define	BE_SWAP32_BUFFER(_b, _c)
2172 #define	BE_SWAP32_BCOPY(_s, _d, _c)	bcopy(_s, _d, _c)
2173 #define	BE_SWAP64(_x)			(_x)
2174 #define	BE_SWAP32(_x)			(_x)
2175 #define	BE_SWAP16(_x)			(_x)
2176 #endif /* EMLXS_BIG_ENDIAN */
2177 
2178 #ifdef	__cplusplus
2179 }
2180 #endif
2181 
2182 #endif	/* _EMLXS_FC_H */
2183