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 2008 Emulex.  All rights reserved.
24  * Use is subject to License terms.
25  */
26 
27 
28 #ifndef _EMLXS_FC_H
29 #define	_EMLXS_FC_H
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 
36 /* ULP Patches: */
37 /* #define	ULP_PATCH1 -  Obsolete */
38 
39 /* This patch enables the driver to auto respond to unsolicited LOGO's */
40 /* This is needed because ULP is sometimes doesn't reply itself */
41 #define	ULP_PATCH2
42 
43 /* This patch enables the driver to auto respond to unsolicited PRLI's */
44 /* This is needed because ULP is known to panic sometimes */
45 #define	ULP_PATCH3
46 
47 /* This patch enables the driver to auto respond to unsolicited PRLO's */
48 /* This is needed because ULP is known to panic sometimes */
49 #define	ULP_PATCH4
50 
51 /* This patch enables the driver to fail pkt abort requests */
52 #define	ULP_PATCH5
53 
54 /* This patch enables the driver to generate an RSCN for unsolicited PRLO's */
55 /* and LOGO's */
56 #define	ULP_PATCH6
57 
58 /* Sun Disk Array Patches: */
59 
60 /* This patch enables the driver to fix a residual underrun issue with */
61 /* check conditions */
62 #define	FCP_UNDERRUN_PATCH1
63 
64 /* This patch enables the driver to fix a residual underrun issue with */
65 /* SCSI inquiry commands */
66 #define	FCP_UNDERRUN_PATCH2
67 
68 /* This patch enables the driver to adjust MAX_RRDY on private loop */
69 /* #define	MAX_RRDY_PATCH */
70 
71 
72 typedef struct emlxs_buf {
73 	fc_packet_t *pkt;		/* scsi_pkt reference */
74 	struct emlxs_port *port;	/* pointer to port */
75 	void *bmp;			/* Save the buffer pointer list */
76 	struct emlxs_buf *fc_fwd;	/* Use it by chip_Q */
77 	struct emlxs_buf *fc_bkwd;	/* Use it by chip_Q */
78 	struct emlxs_buf *next;		/* Use it when the iodone */
79 	void *node;			/* Save node and used by abort */
80 	void *ring;			/* Save ring and used by abort */
81 	struct emlxs_buf *fpkt;		/* Flush pkt pointer */
82 	IOCBQ iocbq;
83 	kmutex_t mtx;
84 	uint32_t pkt_flags;
85 	uint32_t iotag;		/* iotag for this cmd */
86 	uint32_t ticks;		/* save the timeout ticks for the fc_packet_t */
87 	uint32_t abort_attempts;
88 	uint32_t lun;		/* Save LUN id and used by abort */
89 	uint32_t class;		/* Save class and used by abort */
90 	uint32_t ucmd;		/* Unsolicted command that this packet is */
91 				/* responding to, if any */
92 	int32_t flush_count;	/* Valid only in flush pkts */
93 	uint32_t did;
94 
95 #ifdef SFCT_SUPPORT
96 	fc_packet_t *fct_pkt;
97 	fct_cmd_t *fct_cmd;
98 
99 	uint8_t fct_type;
100 
101 #define	EMLXS_FCT_ELS_CMD		0x01	/* Unsolicted */
102 #define	EMLXS_FCT_ELS_REQ		0x02	/* Solicited */
103 #define	EMLXS_FCT_ELS_RSP		0x04
104 
105 #define	EMLXS_FCT_CT_REQ		0x08	/* Solicited */
106 
107 #define	EMLXS_FCT_FCP_CMD		0x10	/* Unsolicted */
108 #define	EMLXS_FCT_FCP_DATA		0x20
109 #define	EMLXS_FCT_FCP_STATUS		0x40
110 
111 
112 	uint8_t fct_flags;
113 
114 #define	EMLXS_FCT_SEND_STATUS		0x01
115 #define	EMLXS_FCT_ABORT			0x02
116 #define	EMLXS_FCT_ABORT_COMPLETE	0x04
117 #define	EMLXS_FCT_REGISTERED		0x10
118 #define	EMLXS_FCT_FLOGI			0x20
119 
120 	uint16_t fct_state;
121 #define	EMLXS_FCT_REQ_CREATED		1
122 #define	EMLXS_FCT_CMD_RECEIVED		2
123 
124 #define	EMLXS_FCT_REG_PENDING		3
125 #define	EMLXS_FCT_REG_COMPLETE		4
126 
127 #define	EMLXS_FCT_REQ_PENDING		5
128 #define	EMLXS_FCT_DATA_PENDING		6
129 #define	EMLXS_FCT_STATUS_PENDING	7
130 #define	EMLXS_FCT_RSP_PENDING		8
131 
132 #define	EMLXS_FCT_REQ_COMPLETE		9
133 #define	EMLXS_FCT_DATA_COMPLETE		10
134 #define	EMLXS_FCT_STATUS_COMPLETE	11
135 #define	EMLXS_FCT_RSP_COMPLETE		12
136 
137 	stmf_data_buf_t *fct_buf;
138 
139 #endif	/* SFCT_SUPPORT */
140 
141 } emlxs_buf_t;
142 
143 
144 /* pkt_flags */
145 #define	PACKET_IN_COMPLETION	0x00000001
146 #define	PACKET_IN_TXQ		0x00000002
147 #define	PACKET_IN_CHIPQ		0x00000004
148 #define	PACKET_IN_DONEQ		0x00000008
149 
150 #define	PACKET_FCP_RESET	0x00000030
151 #define	PACKET_FCP_TGT_RESET	0x00000010
152 #define	PACKET_FCP_LUN_RESET	0x00000020
153 #define	PACKET_POLLED		0x00000040
154 
155 #ifdef EMLXS_I386
156 #define	PACKET_FCP_SWAPPED	0x00000100
157 #define	PACKET_ELS_SWAPPED	0x00000200
158 #define	PACKET_CT_SWAPPED	0x00000400
159 #define	PACKET_CSP_SWAPPED	0x00000800
160 #endif	/* EMLXS_I386 */
161 
162 #define	PACKET_STALE		0x00001000
163 
164 #define	PACKET_IN_TIMEOUT	0x00010000
165 #define	PACKET_IN_FLUSH		0x00020000
166 #define	PACKET_IN_ABORT		0x00040000
167 #define	PACKET_XRI_CLOSED	0x00080000	/* An XRI abort or XRI close */
168 						/* was issued */
169 
170 #define	PACKET_CHIP_COMP	0x00100000
171 #define	PACKET_COMPLETED	0x00200000
172 #define	PACKET_RETURNED		0x00400000
173 
174 #define	PACKET_STATE_VALID	0x01000000
175 #define	PACKET_FCP_RSP_VALID	0x02000000
176 #define	PACKET_ELS_RSP_VALID	0x04000000
177 #define	PACKET_CT_RSP_VALID	0x08000000
178 
179 #define	PACKET_DELAY_REQUIRED	0x10000000
180 #define	PACKET_ALLOCATED	0x40000000
181 #define	PACKET_VALID		0x80000000
182 
183 
184 #define	STALE_PACKET		((emlxs_buf_t *)0xFFFFFFFF)
185 
186 
187 /*
188  * From fc_error.h pkt_reason (except for state = NPORT_RJT, FABRIC_RJT,
189  * NPORT_BSY, FABRIC_BSY, LS_RJT, BA_RJT, FS_RJT)
190  *
191  * FCA unique error codes can begin after FC_REASON_FCA_UNIQUE.
192  * Each FCA defines its own set with values greater >= 0x7F
193  */
194 #define	FC_REASON_FCA_DEFINED   0x100
195 
196 
197 /*
198  * Device VPD save area
199  */
200 
201 typedef struct emlxs_vpd {
202 
203 	uint32_t biuRev;
204 	uint32_t smRev;
205 	uint32_t smFwRev;
206 	uint32_t endecRev;
207 	uint16_t rBit;
208 	uint8_t fcphHigh;
209 	uint8_t fcphLow;
210 	uint8_t feaLevelHigh;
211 	uint8_t feaLevelLow;
212 
213 	uint32_t postKernRev;
214 	char postKernName[32];
215 
216 	uint32_t opFwRev;
217 	char opFwName[32];
218 	char opFwLabel[32];
219 
220 	uint32_t sli1FwRev;
221 	char sli1FwName[32];
222 	char sli1FwLabel[32];
223 
224 	uint32_t sli2FwRev;
225 	char sli2FwName[32];
226 	char sli2FwLabel[32];
227 
228 	uint32_t sli3FwRev;
229 	char sli3FwName[32];
230 	char sli3FwLabel[32];
231 
232 	uint32_t sli4FwRev;
233 	char sli4FwName[32];
234 	char sli4FwLabel[32];
235 
236 	char fw_version[32];
237 	char fw_label[32];
238 
239 	char fcode_version[32];
240 	char boot_version[32];
241 
242 	char serial_num[32];
243 	char part_num[32];
244 	char port_num[20];
245 	char eng_change[32];
246 	char manufacturer[80];
247 	char model[80];
248 	char model_desc[256];
249 	char prog_types[256];
250 	char id[80];
251 
252 	uint32_t port_index;
253 	uint8_t link_speed;
254 
255 } emlxs_vpd_t;
256 
257 
258 typedef struct emlxs_queue {
259 	uint8_t *q_first;	/* queue first element */
260 	uint8_t *q_last;	/* queue last element */
261 	uint16_t q_cnt;	/* current length of queue */
262 	uint16_t q_max;	/* max length queue can get */
263 
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 	int32_t size;		/* Specifies the number of bytes to allocate. */
275 	int32_t align;		/* The desired address boundary. */
276 
277 	int32_t flags;
278 
279 #define	FC_MBUF_DMA		0x01	/* blocks are for DMA */
280 #define	FC_MBUF_PHYSONLY	0x02	/* For malloc - map a given virtual */
281 					/* address to physical (skip malloc) */
282 					/*  For free - just unmap the given  */
283 					/* physical address (skip the free). */
284 #define	FC_MBUF_IOCTL		0x04	/* called from dfc_ioctl */
285 #define	FC_MBUF_UNLOCK		0x08	/* called with driver unlocked */
286 #define	FC_MBUF_SNGLSG		0x10	/* alloc single contiguous physical */
287 					/* memory */
288 #define	FC_MBUF_DMA32		0x20
289 
290 	uint64_t phys;	/* specifies the physical buffer pointer */
291 	void *virt;	/* specifies the virtual buffer pointer */
292 	void *data_handle;
293 	void *dma_handle;
294 
295 } emlxs_buf_info_t;
296 typedef emlxs_buf_info_t MBUF_INFO;
297 
298 
299 
300 #ifdef SLI3_SUPPORT
301 
302 #define	EMLXS_MAX_HBQ   	16	/* Max HBQs handled by firmware */
303 #define	EMLXS_ELS_HBQ_ID	0
304 #define	EMLXS_IP_HBQ_ID		1
305 #define	EMLXS_CT_HBQ_ID		2
306 #define	EMLXS_FCT_HBQ_ID	3
307 
308 #ifdef SFCT_SUPPORT
309 #define	EMLXS_NUM_HBQ		4	/* Number of HBQs supported by driver */
310 #else
311 #define	EMLXS_NUM_HBQ		3	/* Number of HBQs supported by driver */
312 #endif	/* SFCT_SUPPORT */
313 
314 #endif	/* SLI3_SUPPORT */
315 
316 
317 
318 /* Structure used to access adapter rings */
319 typedef struct emlxs_ring {
320 	IOCBQ *fc_iocbhd;	/* ptr to head iocb rsp list for ring */
321 	IOCBQ *fc_iocbtl;	/* ptr to tail iocb rsp list for ring */
322 	void *fc_cmdringaddr;	/* virtual offset for cmd rings */
323 	void *fc_rspringaddr;	/* virtual offset for rsp rings */
324 
325 	emlxs_buf_t **fc_table;	/* sc_buf pointers indexed by iotag */
326 	uint8_t *fc_mpon;	/* index ptr for match structure */
327 	uint8_t *fc_mpoff;	/* index ptr for match structure */
328 	struct emlxs_hba *hba;	/* ptr to hba for ring */
329 
330 	kmutex_t rsp_lock;
331 	IOCBQ *rsp_head;	/* deferred completion head */
332 	IOCBQ *rsp_tail;	/* deferred completion tail */
333 	emlxs_thread_t intr_thread;
334 
335 	uint8_t fc_numCiocb;	/* number of command iocb's per ring */
336 	uint8_t fc_numRiocb;	/* number of rsp iocb's per ring */
337 	uint8_t fc_rspidx;	/* current index in response ring */
338 	uint8_t fc_cmdidx;	/* current index in command ring */
339 	uint8_t fc_port_rspidx;
340 	uint8_t fc_port_cmdidx;
341 	uint8_t ringno;
342 
343 	uint16_t fc_missbufcnt;	/* buf cnt we need to repost */
344 	uint16_t fc_iotag;	/* used to identify I/Os */
345 	uint16_t fc_abort_iotag;	/* used to identify Abort or close */
346 					/* requests */
347 	uint16_t max_iotag;
348 
349 	uint32_t timeout;
350 
351 	/* Protected by EMLXS_RINGTX_LOCK */
352 	emlxs_queue_t nodeq;	/* Node service queue */
353 
354 } emlxs_ring_t;
355 typedef emlxs_ring_t RING;
356 
357 
358 typedef struct emlxs_node {
359 	struct emlxs_node *nlp_list_next;
360 	struct emlxs_node *nlp_list_prev;
361 
362 	NAME_TYPE nlp_portname;	/* port name */
363 	NAME_TYPE nlp_nodename;	/* node name */
364 
365 	uint32_t nlp_DID;	/* fibre channel D_ID of entry */
366 	uint32_t nlp_oldDID;
367 
368 	uint16_t nlp_Rpi;	/* login id returned by REG_LOGIN */
369 	uint16_t nlp_Xri;	/* login id returned by REG_LOGIN */
370 
371 	uint8_t nlp_fcp_info;	/* Remote class info */
372 
373 	/* nlp_fcp_info */
374 #define	NLP_FCP_TGT_DEVICE	0x10	/* FCP TGT device */
375 #define	NLP_FCP_INI_DEVICE	0x20	/* FCP Initiator device */
376 #define	NLP_FCP_2_DEVICE	0x40	/* FCP-2 TGT device */
377 
378 	uint32_t nlp_tag;	/* Tag used by port_offline */
379 	uint32_t flag;
380 
381 #define	NODE_POOL_ALLOCATED	0x00000001
382 
383 	SERV_PARM sparm;
384 
385 	/* Protected by EMLXS_RINGTX_LOCK */
386 	uint32_t nlp_active;	/* Node active flag */
387 	uint32_t nlp_base;
388 	uint32_t nlp_flag[MAX_RINGS];	/* Node level ring flags */
389 
390 	/* nlp_flag */
391 #define	NLP_CLOSED		0x1	/* Node closed */
392 #define	NLP_TIMER		0x2	/* Node timer is active */
393 #define	NLP_RPI_XRI		0x4	/* Create xri for entry */
394 
395 	uint32_t nlp_tics[MAX_RINGS];	/* gate timeout */
396 	emlxs_queue_t nlp_tx[MAX_RINGS];	/* Transmit Q head */
397 	emlxs_queue_t nlp_ptx[MAX_RINGS];	/* Priority transmit Q head */
398 	void *nlp_next[MAX_RINGS];	/* Service Request Q pointer - used */
399 					/* when node needs servicing */
400 #ifdef DHCHAP_SUPPORT
401 	emlxs_node_dhc_t node_dhc;
402 #endif	/* DHCHAP_SUPPORT */
403 
404 } emlxs_node_t;
405 typedef emlxs_node_t NODELIST;
406 
407 
408 
409 #define	NADDR_LEN	6	/* MAC network address length */
410 typedef struct emlxs_fcip_nethdr {
411 	NAME_TYPE fc_destname;	/* destination port name */
412 	NAME_TYPE fc_srcname;	/* source port name */
413 
414 } emlxs_fcip_nethdr_t;
415 typedef emlxs_fcip_nethdr_t NETHDR;
416 
417 
418 #define	MEM_NLP		0	/* memory segment to hold node list entries */
419 #define	MEM_IOCB	1	/* memory segment to hold iocb commands */
420 #define	MEM_MBOX	2	/* memory segment to hold mailbox cmds */
421 #define	MEM_BPL		3	/* and to hold buffer ptr lists - SLI2 */
422 #define	MEM_BUF		4	/* memory segment to hold buffer data */
423 #define	MEM_ELSBUF	4	/* memory segment to hold buffer data */
424 #define	MEM_IPBUF	5	/* memory segment to hold IP buffer data */
425 #define	MEM_CTBUF	6	/* memory segment to hold CT buffer data */
426 #define	MEM_FCTBUF	7	/* memory segment to hold FCT buffer data */
427 
428 #ifdef SFCT_SUPPORT
429 #define	FC_MAX_SEG	8
430 #else
431 #define	FC_MAX_SEG	7
432 #endif	/* SFCT_SUPPORT */
433 
434 
435 /* A BPL entry is 12 bytes. Subtract 2 for command and response buffers */
436 #define	BPL_TO_SGLLEN(_bpl) ((_bpl/12)-2)
437 
438 #define	MEM_BPL_SIZE		1024	/* Default size */
439 
440 #ifdef EMLXS_I386
441 #define	EMLXS_SGLLEN		BPL_TO_SGLLEN(MEM_BPL_SIZE)
442 #else	/* EMLXS_SPARC */
443 #define	EMLXS_SGLLEN		1
444 #endif	/* EMLXS_I386 */
445 
446 #define	MEM_BUF_SIZE		1024
447 #define	MEM_BUF_COUNT		64
448 
449 #define	MEM_ELSBUF_SIZE		MEM_BUF_SIZE
450 #define	MEM_ELSBUF_COUNT	hba->max_nodes
451 #define	MEM_IPBUF_SIZE		65535
452 #define	MEM_IPBUF_COUNT		60
453 #define	MEM_CTBUF_SIZE		MAX_CT_PAYLOAD	/* (1024*320) */
454 #define	MEM_CTBUF_COUNT		8
455 #define	MEM_FCTBUF_SIZE		65535
456 #define	MEM_FCTBUF_COUNT	128
457 
458 #define	MEM_SEG_MASK		0xff	/* mask off the priority bit */
459 #define	MEM_PRI 		0x100	/* Priority bit: exceed low water */
460 
461 
462 
463 typedef struct emlxs_memseg {
464 	uint8_t *fc_memget_ptr;
465 	uint8_t *fc_memget_end;
466 	uint8_t *fc_memput_ptr;
467 	uint8_t *fc_memput_end;
468 
469 	uint8_t *fc_memstart_virt;	/* beginning address of the memory */
470 					/* block */
471 	uint64_t fc_memstart_phys;	/* beginning address of the memory */
472 					/* block */
473 	ddi_dma_handle_t fc_mem_dma_handle;
474 	ddi_acc_handle_t fc_mem_dat_handle;
475 	uint32_t fc_total_memsize;
476 	uint32_t fc_memsize;	/* size of memory blocks */
477 	uint32_t fc_numblks;	/* number of memory blocks */
478 	uint32_t fc_memget_cnt;	/* number of memory get blocks */
479 	uint32_t fc_memput_cnt;	/* number of memory put blocks */
480 	uint32_t fc_memflag;	/* what to do when list is exhausted */
481 	uint32_t fc_lowmem;	/* low water mark, used w/MEM_PRI flag */
482 
483 } emlxs_memseg_t;
484 typedef emlxs_memseg_t MEMSEG;
485 
486 
487 #define	FC_MEM_ERR	1	/* return error memflag */
488 #define	FC_MEM_GETMORE	2	/* get more memory memflag */
489 #define	FC_MEM_DMA	4	/* blocks are for DMA */
490 #define	FC_MEM_LOWHIT	8	/* low water mark was hit */
491 #define	FC_MEMPAD	16	/* offset used for a FC_MEM_DMA buffer */
492 
493 /* Board stat counters */
494 typedef struct emlxs_stats {
495 	uint32_t LinkUp;
496 	uint32_t LinkDown;
497 	uint32_t LinkEvent;
498 	uint32_t LinkMultiEvent;
499 
500 	uint32_t MboxIssued;
501 	uint32_t MboxCompleted;	/* MboxCompleted = MboxError + MbxGood */
502 	uint32_t MboxGood;
503 	uint32_t MboxError;
504 	uint32_t MboxBusy;
505 	uint32_t MboxInvalid;
506 
507 	uint32_t IocbIssued[MAX_RINGS];
508 	uint32_t IocbReceived[MAX_RINGS];
509 	uint32_t IocbTxPut[MAX_RINGS];
510 	uint32_t IocbTxGet[MAX_RINGS];
511 	uint32_t IocbRingFull[MAX_RINGS];
512 	uint32_t IocbThrottled;
513 
514 	uint32_t IntrEvent[8];
515 
516 	uint32_t FcpIssued;
517 	uint32_t FcpCompleted;	/* = FcpGood + FcpError */
518 	uint32_t FcpGood;
519 	uint32_t FcpError;
520 
521 	uint32_t FcpEvent;	/* = FcpStray + FcpCompleted */
522 	uint32_t FcpStray;
523 #ifdef SFCT_SUPPORT
524 	uint32_t FctRingEvent;
525 	uint32_t FctRingError;
526 	uint32_t FctRingDropped;
527 #endif	/* SFCT_SUPPORT */
528 
529 	uint32_t ElsEvent;	/* = ElsStray + ElsCmdCompleted + */
530 				/* ElsRspCompleted */
531 	uint32_t ElsStray;
532 
533 	uint32_t ElsCmdIssued;
534 	uint32_t ElsCmdCompleted;	/* = ElsCmdGood + ElsCmdError */
535 	uint32_t ElsCmdGood;
536 	uint32_t ElsCmdError;
537 
538 	uint32_t ElsRspIssued;
539 	uint32_t ElsRspCompleted;
540 
541 	uint32_t ElsRcvEvent;	/* = ElsRcvError + ElsRcvDropped + */
542 				/* ElsCmdReceived */
543 	uint32_t ElsRcvError;
544 	uint32_t ElsRcvDropped;
545 	uint32_t ElsCmdReceived;	/* = ElsRscnReceived + */
546 					/* ElsPlogiReceived + ... */
547 	uint32_t ElsRscnReceived;
548 	uint32_t ElsFlogiReceived;
549 	uint32_t ElsPlogiReceived;
550 	uint32_t ElsPrliReceived;
551 	uint32_t ElsPrloReceived;
552 	uint32_t ElsLogoReceived;
553 	uint32_t ElsAdiscReceived;
554 	uint32_t ElsAuthReceived;
555 	uint32_t ElsGenReceived;
556 
557 	uint32_t CtEvent;	/* = CtStray + CtCmdCompleted + */
558 				/* CtRspCompleted */
559 	uint32_t CtStray;
560 
561 	uint32_t CtCmdIssued;
562 	uint32_t CtCmdCompleted;	/* = CtCmdGood + CtCmdError */
563 	uint32_t CtCmdGood;
564 	uint32_t CtCmdError;
565 
566 	uint32_t CtRspIssued;
567 	uint32_t CtRspCompleted;
568 
569 	uint32_t CtRcvEvent;	/* = CtRcvError + CtRcvDropped + */
570 				/* CtCmdReceived */
571 	uint32_t CtRcvError;
572 	uint32_t CtRcvDropped;
573 	uint32_t CtCmdReceived;
574 
575 	uint32_t IpEvent;	/* = IpStray + IpSeqCompleted + */
576 				/* IpBcastCompleted */
577 	uint32_t IpStray;
578 
579 	uint32_t IpSeqIssued;
580 	uint32_t IpSeqCompleted;	/* = IpSeqGood + IpSeqError */
581 	uint32_t IpSeqGood;
582 	uint32_t IpSeqError;
583 
584 	uint32_t IpBcastIssued;
585 	uint32_t IpBcastCompleted;	/* = IpBcastGood + IpBcastError */
586 	uint32_t IpBcastGood;
587 	uint32_t IpBcastError;
588 
589 	uint32_t IpRcvEvent;	/* = IpDropped + IpSeqReceived + */
590 				/* IpBcastReceived */
591 	uint32_t IpDropped;
592 	uint32_t IpSeqReceived;
593 	uint32_t IpBcastReceived;
594 
595 	uint32_t IpUbPosted;
596 	uint32_t ElsUbPosted;
597 	uint32_t CtUbPosted;
598 #ifdef SFCT_SUPPORT
599 	uint32_t FctUbPosted;
600 #endif	/* SFCT_SUPPORT */
601 
602 	uint32_t ResetTime;	/* Time of last reset */
603 
604 } emlxs_stats_t;
605 
606 
607 #define	FC_MAX_ADPTMSG		(8*28)	/* max size of a msg from adapter */
608 
609 #define	EMLXS_NUM_THREADS	8
610 #define	EMLXS_MIN_TASKS		8
611 #define	EMLXS_MAX_TASKS		8
612 
613 #define	EMLXS_NUM_HASH_QUES	32
614 #define	EMLXS_DID_HASH(x)	((x) & (EMLXS_NUM_HASH_QUES - 1))
615 
616 
617 /* pkt_tran_flag */
618 #define	FC_TRAN_COMPLETED	0x8000
619 
620 
621 typedef struct emlxs_dfc_event {
622 	uint32_t pid;
623 	uint32_t event;
624 	uint32_t last_id;
625 
626 	void *dataout;
627 	uint32_t size;
628 	uint32_t mode;
629 
630 } emlxs_dfc_event_t;
631 
632 
633 typedef struct emlxs_hba_event {
634 	uint32_t last_id;
635 	uint32_t new;
636 	uint32_t missed;
637 
638 } emlxs_hba_event_t;
639 
640 
641 #ifdef SFCT_SUPPORT
642 
643 #define	TGTPORTSTAT			port->fct_stat
644 
645 /*
646  * FctP2IOXcnt will count IOs by their fcpDL. Counters
647  * are for buckets of various power of 2 sizes.
648  * Bucket 0  <  512  > 0
649  * Bucket 1  >= 512  < 1024
650  * Bucket 2  >= 1024 < 2048
651  * Bucket 3  >= 2048 < 4096
652  * Bucket 4  >= 4096 < 8192
653  * Bucket 5  >= 8192 < 16K
654  * Bucket 6  >= 16K  < 32K
655  * Bucket 7  >= 32K  < 64K
656  * Bucket 8  >= 64K  < 128K
657  * Bucket 9  >= 128K < 256K
658  * Bucket 10 >= 256K < 512K
659  * Bucket 11 >= 512K < 1MB
660  * Bucket 12 >= 1MB  < 2MB
661  * Bucket 13 >= 2MB  < 4MB
662  * Bucket 14 >= 4MB  < 8MB
663  * Bucket 15 >= 8MB
664  */
665 #define	MAX_TGTPORT_IOCNT	16
666 
667 
668 /*
669  * These routines will bump the right counter, based on
670  * the size of the IO inputed, with the least number of
671  * comparisions.  A max of 5 comparisions is only needed
672  * to classify the IO in one of 16 ranges. A binary search
673  * to locate the high bit in the size is used.
674  */
675 #define	emlxs_bump_rdioctr(port, cnt)					\
676 {									\
677 	/* Use binary search to find the first high bit */		\
678 	if (cnt & 0xffff0000) {						\
679 		if (cnt & 0xff800000) {					\
680 			TGTPORTSTAT.FctP2IORcnt[15]++;			\
681 		}							\
682 		else {							\
683 			/* It must be 0x007f0000 */			\
684 			if (cnt & 0x00700000) {				\
685 				if (cnt & 0x00400000) {			\
686 					TGTPORTSTAT.FctP2IORcnt[14]++;	\
687 				}					\
688 				else {					\
689 					/* It must be 0x00300000 */	\
690 					if (cnt & 0x00200000) {		\
691 						TGTPORTSTAT.FctP2IORcnt[13]++;\
692 					}				\
693 					else {				\
694 						/* It must be 0x00100000 */   \
695 						TGTPORTSTAT.FctP2IORcnt[12]++;\
696 					}				\
697 				}					\
698 			}						\
699 			else {						\
700 				/* It must be 0x000f0000 */		\
701 				if (cnt & 0x000c0000) {			\
702 					if (cnt & 0x00080000) {		\
703 						TGTPORTSTAT.FctP2IORcnt[11]++; \
704 					}				\
705 					else {				\
706 						/* It must be 0x00040000  */   \
707 						TGTPORTSTAT.FctP2IORcnt[10]++; \
708 					}				\
709 				}					\
710 				else {					\
711 					/* It must be 0x00030000 */	\
712 					if (cnt & 0x00020000) {		\
713 						TGTPORTSTAT.FctP2IORcnt[9]++;  \
714 					}				\
715 					else {				\
716 						/* It must be 0x00010000   */  \
717 						TGTPORTSTAT.FctP2IORcnt[8]++;  \
718 					}				\
719 				}					\
720 			}						\
721 		}							\
722 	}								\
723 	else {								\
724 		if (cnt & 0x0000fe00) {					\
725 			if (cnt & 0x0000f000) {				\
726 				if (cnt & 0x0000c000) {			\
727 					if (cnt & 0x00008000) {		\
728 						TGTPORTSTAT.FctP2IORcnt[7]++;  \
729 					}				\
730 					else {				\
731 						/* It must be 0x00004000   */  \
732 						TGTPORTSTAT.FctP2IORcnt[6]++;  \
733 					}				\
734 				}					\
735 				else {					\
736 					/* It must be 0x00000300 */	\
737 					if (cnt & 0x00000200) {		\
738 						TGTPORTSTAT.FctP2IORcnt[5]++;  \
739 					}				\
740 					else {				\
741 						/* It must be 0x00000100   */  \
742 						TGTPORTSTAT.FctP2IORcnt[4]++;  \
743 					}				\
744 				}					\
745 			}						\
746 			else {						\
747 				/* It must be 0x00000e00 */		\
748 				if (cnt & 0x00000800) {			\
749 					TGTPORTSTAT.FctP2IORcnt[3]++;	\
750 				}					\
751 				else {					\
752 					/* It must be 0x00000600 */	\
753 					if (cnt & 0x00000400) {		\
754 						TGTPORTSTAT.FctP2IORcnt[2]++;  \
755 					}				\
756 					else {				\
757 						/* It must be 0x00000200   */  \
758 						TGTPORTSTAT.FctP2IORcnt[1]++;  \
759 					}				\
760 				}					\
761 			}						\
762 		}							\
763 		else {							\
764 			/* It must be 0x000001ff */			\
765 			TGTPORTSTAT.FctP2IORcnt[0]++;			\
766 		}							\
767 	}								\
768 }
769 
770 #define	emlxs_bump_wrioctr(port, cnt)					\
771 {									\
772 	/* Use binary search to find the first high bit */		\
773 	if (cnt & 0xffff0000) {						\
774 		if (cnt & 0xff800000) {					\
775 			TGTPORTSTAT.FctP2IOWcnt[15]++;			\
776 		}							\
777 		else {							\
778 			/* It must be 0x007f0000 */			\
779 			if (cnt & 0x00700000) {				\
780 				if (cnt & 0x00400000) {			\
781 					TGTPORTSTAT.FctP2IOWcnt[14]++;	\
782 				}					\
783 				else {					\
784 					/* It must be 0x00300000 */	\
785 					if (cnt & 0x00200000) {		\
786 						TGTPORTSTAT.FctP2IOWcnt[13]++; \
787 					}				\
788 					else {				\
789 						/* It must be 0x00100000   */  \
790 						TGTPORTSTAT.FctP2IOWcnt[12]++; \
791 					}				\
792 				}					\
793 			}						\
794 			else {						\
795 				/* It must be 0x000f0000 */		\
796 				if (cnt & 0x000c0000) {			\
797 					if (cnt & 0x00080000) {		\
798 						TGTPORTSTAT.FctP2IOWcnt[11]++; \
799 					}				\
800 					else {				\
801 						/* It must be 0x00040000   */  \
802 						TGTPORTSTAT.FctP2IOWcnt[10]++; \
803 					}				\
804 				}					\
805 				else {					\
806 					/* It must be 0x00030000 */	\
807 					if (cnt & 0x00020000) {		\
808 						TGTPORTSTAT.FctP2IOWcnt[9]++; \
809 					}				\
810 					else {				\
811 						/* It must be 0x00010000  */  \
812 						TGTPORTSTAT.FctP2IOWcnt[8]++; \
813 					}				\
814 				}					\
815 			}						\
816 		}							\
817 	}								\
818 	else {								\
819 		if (cnt & 0x0000fe00) {					\
820 			if (cnt & 0x0000f000) {				\
821 				if (cnt & 0x0000c000) {			\
822 					if (cnt & 0x00008000) {		\
823 						TGTPORTSTAT.FctP2IOWcnt[7]++; \
824 					}				\
825 					else {				\
826 						/* It must be 0x00004000  */  \
827 						TGTPORTSTAT.FctP2IOWcnt[6]++; \
828 					}				\
829 				}					\
830 				else {					\
831 					/* It must be 0x00000300 */	\
832 					if (cnt & 0x00000200) {		\
833 						TGTPORTSTAT.FctP2IOWcnt[5]++; \
834 					}				\
835 					else {				\
836 						/* It must be 0x00000100  */  \
837 						TGTPORTSTAT.FctP2IOWcnt[4]++; \
838 					}				\
839 				}					\
840 			}						\
841 			else {						\
842 				/* It must be 0x00000e00 */		\
843 				if (cnt & 0x00000800) {			\
844 					TGTPORTSTAT.FctP2IOWcnt[3]++;	\
845 				}					\
846 				else {					\
847 					/* It must be 0x00000600 */	\
848 					if (cnt & 0x00000400) {		\
849 						TGTPORTSTAT.FctP2IOWcnt[2]++; \
850 					}				\
851 					else {				\
852 						/* It must be 0x00000200  */  \
853 						TGTPORTSTAT.FctP2IOWcnt[1]++; \
854 					}				\
855 				}					\
856 			}						\
857 		}							\
858 		else {							\
859 			/* It must be 0x000001ff */			\
860 			TGTPORTSTAT.FctP2IOWcnt[0]++;			\
861 		}							\
862 	}								\
863 }
864 
865 typedef struct emlxs_tgtport_stat {
866 	/* IO counters */
867 	uint64_t FctP2IOWcnt[MAX_TGTPORT_IOCNT];	/* Writes */
868 	uint64_t FctP2IORcnt[MAX_TGTPORT_IOCNT];	/* Reads  */
869 	uint64_t FctIOCmdCnt;	/* Other, ie TUR */
870 	uint64_t FctCmdReceived;	/* total IOs */
871 	uint64_t FctReadBytes;	/* total bytes Read */
872 	uint64_t FctWriteBytes;	/* total bytes Written */
873 
874 	/* IOCB handling counters */
875 	uint64_t FctEvent;	/* = FctStray + FctCompleted */
876 	uint64_t FctCompleted;	/* = FctCmplGood + FctCmplError */
877 	uint64_t FctCmplGood;
878 
879 	uint32_t FctCmplError;
880 	uint32_t FctStray;
881 
882 	/* Fct event counters */
883 	uint32_t FctRcvDropped;
884 	uint32_t FctOverQDepth;
885 	uint32_t FctOutstandingIO;
886 	uint32_t FctFailedPortRegister;
887 	uint32_t FctPortRegister;
888 	uint32_t FctPortDeregister;
889 
890 	uint32_t FctAbortSent;
891 	uint32_t FctNoBuffer;
892 	uint32_t FctScsiStatusErr;
893 	uint32_t FctScsiQfullErr;
894 	uint32_t FctScsiResidOver;
895 	uint32_t FctScsiResidUnder;
896 	uint32_t FctScsiSenseErr;
897 
898 	uint32_t FctFiller1;
899 } emlxs_tgtport_stat_t;
900 #endif	/* SFCT_SUPPORT */
901 
902 
903 /*
904  * Port Information Data Structure
905  */
906 
907 typedef struct emlxs_port {
908 	struct emlxs_hba *hba;
909 
910 	/* Virtual port management */
911 	uint32_t vpi;
912 	uint32_t flag;
913 #define	EMLXS_PORT_ENABLE		0x00000001
914 #define	EMLXS_PORT_BOUND		0x00000002
915 
916 #define	EMLXS_PORT_REGISTERED		0x00010000	/* VPI registered */
917 #define	EMLXS_PORT_IP_UP		0x00000010
918 #define	EMLXS_PORT_CONFIG		0x00000020
919 #define	EMLXS_PORT_RESTRICTED		0x00000040	/* Restrict login flg */
920 #define	EMLXS_PORT_FLOGI_CMPL		0x00000080	/* Fabric login cmpl */
921 
922 #define	EMLXS_PORT_RESET_MASK		0x0000FFFF	/* Flags kept across */
923 							/* a hard reset */
924 #define	EMLXS_PORT_LINKDOWN_MASK	0xFFFFFFFF	/* Flags kept across */
925 							/* a link reset */
926 
927 	uint32_t options;
928 #define	EMLXS_OPT_RESTRICT		0x00000001	/* Force restricted */
929 							/* logins   */
930 #define	EMLXS_OPT_UNRESTRICT		0x00000002	/* Force Unrestricted */
931 							/* logins */
932 #define	EMLXS_OPT_RESTRICT_MASK		0x00000003
933 
934 
935 	/* FC world wide names */
936 	NAME_TYPE wwnn;
937 	NAME_TYPE wwpn;
938 	char snn[256];
939 	char spn[256];
940 
941 	/* Common service paramters */
942 	SERV_PARM sparam;
943 	SERV_PARM fabric_sparam;
944 
945 	/* fc_id management */
946 	uint32_t did;
947 	uint32_t prev_did;
948 
949 	/* FC_AL management */
950 	uint8_t lip_type;
951 	uint8_t alpa_map[128];
952 
953 	/* Node management */
954 	emlxs_node_t node_base;
955 	uint32_t node_count;
956 	krwlock_t node_rwlock;
957 	emlxs_node_t *node_table[EMLXS_NUM_HASH_QUES];
958 
959 	/* Polled packet management */
960 	kcondvar_t pkt_lock_cv;	/* pkt polling */
961 	kmutex_t pkt_lock;	/* pkt polling */
962 
963 	/* ULP */
964 	uint32_t ulp_statec;
965 	void (*ulp_statec_cb) ();	/* Port state change callback routine */
966 	void (*ulp_unsol_cb) ();	/* unsolicited event callback routine */
967 	opaque_t ulp_handle;
968 
969 	/* ULP unsolicited buffers */
970 	kmutex_t ub_lock;
971 	uint32_t ub_count;
972 	emlxs_unsol_buf_t *ub_pool;
973 	uint32_t ub_post[MAX_RINGS];
974 	uint32_t ub_timer;
975 
976 	emlxs_ub_priv_t *ub_wait_head;	/* Unsolicited IO received before */
977 					/* link up */
978 	emlxs_ub_priv_t *ub_wait_tail;	/* Unsolicited IO received before */
979 					/* link up */
980 
981 
982 #ifdef DHCHAP_SUPPORT
983 	emlxs_port_dhc_t port_dhc;
984 #endif	/* DHCHAP_SUPPORT */
985 
986 	uint16_t ini_mode;
987 	uint16_t tgt_mode;
988 
989 #ifdef SFCT_SUPPORT
990 
991 #define	FCT_BUF_COUNT_512		256
992 #define	FCT_BUF_COUNT_8K		128
993 #define	FCT_BUF_COUNT_64K		64
994 #define	FCT_BUF_COUNT_128K		64
995 #define	FCT_MAX_BUCKETS			16
996 #define	FCT_DMEM_MAX_BUF_SIZE		(2 * 65536)
997 
998 	struct emlxs_fct_dmem_bucket dmem_bucket[FCT_MAX_BUCKETS];
999 	int fct_queue_depth;
1000 
1001 	char cfd_name[24];
1002 	stmf_port_provider_t *port_provider;
1003 	fct_local_port_t *fct_port;
1004 	uint32_t fct_flags;
1005 
1006 #define	FCT_STATE_PORT_ONLINE	0x00000001
1007 #define	FCT_STATE_NOT_ACKED	0x00000002
1008 #define	FCT_STATE_LINK_UP	0x00000010
1009 
1010 	emlxs_buf_t *fct_wait_head;
1011 	emlxs_buf_t *fct_wait_tail;
1012 	emlxs_tgtport_stat_t fct_stat;
1013 
1014 #endif	/* SFCT_SUPPORT */
1015 
1016 } emlxs_port_t;
1017 
1018 
1019 
1020 /* Host Attn reg */
1021 #define	FC_HA_REG(_hba, _sa)	((volatile uint32_t *) \
1022 				((volatile char *)_sa + ((_hba)->ha_reg_addr)))
1023 
1024 /* Chip Attn reg */
1025 #define	FC_CA_REG(_hba, _sa)	((volatile uint32_t *) \
1026 				((volatile char *)_sa + ((_hba)->ca_reg_addr)))
1027 
1028 /* Host Status reg */
1029 #define	FC_HS_REG(_hba, _sa)	((volatile uint32_t *) \
1030 				((volatile char *)_sa + ((_hba)->hs_reg_addr)))
1031 
1032 /* Host Cntl reg */
1033 #define	FC_HC_REG(_hba, _sa)	((volatile uint32_t *) \
1034 				((volatile char *)_sa + ((_hba)->hc_reg_addr)))
1035 
1036 /* BIU Configuration reg */
1037 #define	FC_BC_REG(_hba, _sa)	((volatile uint32_t *) \
1038 				((volatile char *)_sa + ((_hba)->bc_reg_addr)))
1039 
1040 /* Used by SBUS adapter */
1041 /* TITAN Cntl reg */
1042 #define	FC_SHC_REG(_hba, _sa)	((volatile uint32_t *) \
1043 				((volatile char *)_sa + ((_hba)->shc_reg_addr)))
1044 
1045 /* TITAN Status reg */
1046 #define	FC_SHS_REG(_hba, _sa)	((volatile uint32_t *) \
1047 				((volatile char *)_sa + ((_hba)->shs_reg_addr)))
1048 
1049 /* TITAN Update reg */
1050 #define	FC_SHU_REG(_hba, _sa)	((volatile uint32_t *) \
1051 				((volatile char *)_sa + ((_hba)->shu_reg_addr)))
1052 
1053 
1054 #define	FC_SLIM2_MAILBOX(_hba)	((MAILBOX *)(_hba)->slim2.virt)
1055 
1056 #define	FC_SLIM1_MAILBOX(_hba)	((MAILBOX *)(_hba)->slim_addr)
1057 
1058 #define	FC_MAILBOX(_hba)	(((_hba)->flag & FC_SLIM2_MODE) ? \
1059 				FC_SLIM2_MAILBOX(_hba):FC_SLIM1_MAILBOX(_hba))
1060 
1061 #define	WRITE_CSR_REG(_hba, _regp, _value)	\
1062 	(void) ddi_put32((_hba)->csr_acc_handle,\
1063 	(uint32_t *)(_regp),\
1064 	(uint32_t)(_value))
1065 
1066 #define	READ_CSR_REG(_hba, _regp)	\
1067 	ddi_get32((_hba)->csr_acc_handle,\
1068 	(uint32_t *)(_regp))
1069 
1070 #define	WRITE_SLIM_ADDR(_hba, _regp, _value)	\
1071 	(void) ddi_put32((_hba)->slim_acc_handle,\
1072 	(uint32_t *)(_regp),\
1073 	(uint32_t)(_value))
1074 
1075 #define	READ_SLIM_ADDR(_hba, _regp)	\
1076 	ddi_get32((_hba)->slim_acc_handle,\
1077 	(uint32_t *)(_regp))
1078 
1079 #define	WRITE_SLIM_COPY(_hba, _bufp, _slimp, _wcnt)	\
1080 	(void) ddi_rep_put32((_hba)->slim_acc_handle,\
1081 	(uint32_t *)(_bufp),\
1082 	(uint32_t *)(_slimp),\
1083 	(_wcnt),\
1084 	DDI_DEV_AUTOINCR)
1085 
1086 #define	READ_SLIM_COPY(_hba, _bufp, _slimp, _wcnt)	\
1087 	(void) ddi_rep_get32((_hba)->slim_acc_handle,\
1088 	(uint32_t *)(_bufp),\
1089 	(uint32_t *)(_slimp),\
1090 	(_wcnt),\
1091 	DDI_DEV_AUTOINCR)
1092 
1093 #define	WRITE_FLASH_COPY(_hba, _bufp, _flashp, _wcnt)	\
1094 	(void) ddi_rep_put32((_hba)->fc_flash_handle,\
1095 	(uint32_t *)(_bufp),\
1096 	(uint32_t *)(_flashp),\
1097 	(_wcnt),\
1098 	DDI_DEV_AUTOINCR)
1099 
1100 #define	READ_FLASH_COPY(_hba, _bufp, _flashp, _wcnt)	\
1101 	(void) ddi_rep_get32((_hba)->fc_flash_handle, (uint32_t *)(_bufp),\
1102 	(uint32_t *)(_flashp),\
1103 	(_wcnt),\
1104 	DDI_DEV_AUTOINCR)
1105 
1106 /* Used by SBUS adapter */
1107 #define	WRITE_SBUS_CSR_REG(_hba, _regp, _value)		\
1108 	(void) ddi_put32((_hba)->sbus_csr_handle,\
1109 	(uint32_t *)(_regp),\
1110 	(uint32_t)(_value))
1111 
1112 #define	READ_SBUS_CSR_REG(_hba, _regp)		\
1113 	ddi_get32((_hba)->sbus_csr_handle,\
1114 	(uint32_t *)(_regp))
1115 
1116 #define	SBUS_WRITE_FLASH_COPY(_hba, _offset, _value)	\
1117 	(void) ddi_put8((_hba)->sbus_flash_acc_handle,\
1118 	(uint8_t *)((volatile uint8_t *)(_hba)->sbus_flash_addr + (_offset)),\
1119 	(uint8_t)(_value))
1120 
1121 #define	SBUS_READ_FLASH_COPY(_hba, _offset)	\
1122 	ddi_get8((_hba)->sbus_flash_acc_handle,\
1123 	(uint8_t *)((volatile uint8_t *)(_hba)->sbus_flash_addr + (_offset)))
1124 
1125 #define	emlxs_ffstate_change(_hba, _state)				\
1126 {									\
1127 	mutex_enter(&EMLXS_PORT_LOCK);					\
1128 	emlxs_ffstate_change_locked((_hba), (_state));			\
1129 	mutex_exit(&EMLXS_PORT_LOCK);					\
1130 }
1131 
1132 /* Used when EMLXS_PORT_LOCK is already held */
1133 #define	emlxs_ffstate_change_locked(_hba, _state)			\
1134 {									\
1135 	if ((_hba)->state != (_state))					\
1136 	{								\
1137 		uint32_t _st = _state;					\
1138 		EMLXS_MSGF(EMLXS_CONTEXT,				\
1139 			&emlxs_state_msg, "%s --> %s",			\
1140 			emlxs_ffstate_xlate((_hba)->state),		\
1141 			emlxs_ffstate_xlate(_state));			\
1142 		(_hba)->state = (_state);				\
1143 		if ((_st) == FC_ERROR)				\
1144 		{							\
1145 			(_hba)->flag |= FC_HARDWARE_ERROR;		\
1146 		}							\
1147 	}								\
1148 }
1149 
1150 /*
1151  * This is the HBA control area for the adapter
1152  */
1153 
1154 #ifdef MODSYM_SUPPORT
1155 
1156 typedef struct emlxs_modsym {
1157 	ddi_modhandle_t mod_fctl;	/* For Leadville */
1158 
1159 	/* Leadville (fctl) */
1160 	int (*fc_fca_attach) (dev_info_t *, fc_fca_tran_t *);
1161 	int (*fc_fca_detach) (dev_info_t *);
1162 	int (*fc_fca_init) (struct dev_ops *);
1163 
1164 #ifdef SFCT_SUPPORT
1165 	ddi_modhandle_t mod_fct;	/* For Comstar */
1166 	ddi_modhandle_t mod_stmf;	/* For Comstar */
1167 
1168 	/* Comstar (fct) */
1169 	void *(*fct_alloc) (int, int, int);
1170 	void (*fct_free) (void *);
1171 	void *(*fct_scsi_task_alloc) (void *, int, int, uint8_t *, int, int);
1172 	int (*fct_register_local_port) (fct_local_port_t *);
1173 	void (*fct_deregister_local_port) (fct_local_port_t *);
1174 	void (*fct_handle_event) (fct_local_port_t *, int, int, int);
1175 	void (*fct_post_rcvd_cmd) (fct_cmd_t *, int);
1176 	void (*fct_ctl) (void *, int, stmf_change_status_t *);
1177 	void (*fct_send_response_done) (fct_cmd_t *, int, int);
1178 	void (*fct_send_cmd_done) (fct_cmd_t *, int, int);
1179 	void (*fct_scsi_data_xfer_done) (fct_cmd_t *, stmf_data_buf_t *, int);
1180 	fct_status_t(*fct_port_shutdown) (fct_local_port_t *, uint32_t, char *);
1181 	fct_status_t(*fct_port_initialize)
1182 		(fct_local_port_t *, uint32_t, char *);
1183 	fct_status_t(*fct_handle_rcvd_flogi)
1184 		(fct_local_port_t *, fct_flogi_xchg_t *);
1185 
1186 	/* Comstar (stmf) */
1187 	void *(*stmf_alloc) (int, int, int);
1188 	void (*stmf_free) (void *);
1189 	void (*stmf_deregister_port_provider) (stmf_port_provider_t *);
1190 	int (*stmf_register_port_provider) (stmf_port_provider_t *);
1191 
1192 #endif	/* SFCT_SUPPORT */
1193 
1194 } emlxs_modsym_t;
1195 extern emlxs_modsym_t emlxs_modsym;
1196 
1197 #define	MODSYM(_f)		emlxs_modsym._f
1198 
1199 #else
1200 
1201 #define	MODSYM(_f)		_f
1202 
1203 #endif	/* MODSYM_SUPPORT */
1204 
1205 
1206 
1207 #define	PCI_CONFIG_SIZE		0x80
1208 
1209 typedef struct emlxs_hba {
1210 	dev_info_t *dip;
1211 	int32_t emlxinst;
1212 	int32_t ddiinst;
1213 	fc_fca_tran_t *fca_tran;
1214 
1215 	/* HBA Info */
1216 	emlxs_model_t model_info;
1217 	emlxs_vpd_t vpd;	/* vital product data */
1218 	NAME_TYPE wwnn;
1219 	NAME_TYPE wwpn;
1220 	char snn[256];
1221 	char spn[256];
1222 	PROG_ID load_list[MAX_LOAD_ENTRY];
1223 	WAKE_UP_PARMS wakeup_parms;
1224 	uint32_t max_nodes;
1225 	uint32_t io_throttle;
1226 	uint32_t io_active;
1227 	uint32_t bus_type;
1228 #define	PCI_FC		0
1229 #define	SBUS_FC		1
1230 
1231 	/* Link management */
1232 	uint32_t link_event_tag;
1233 	uint8_t topology;
1234 	uint8_t linkspeed;
1235 	uint32_t linkup_wait_flag;
1236 	kcondvar_t linkup_lock_cv;
1237 	kmutex_t linkup_lock;
1238 
1239 	/* Memory Pool management */
1240 	uint32_t mem_bpl_size;
1241 	emlxs_memseg_t memseg[FC_MAX_SEG];	/* memory for buffers */
1242 						/* structures */
1243 	kmutex_t memget_lock;	/* locks all memory pools get */
1244 	kmutex_t memput_lock;	/* locks all memory pools put */
1245 
1246 	/* Fibre Channel Service Parameters */
1247 	SERV_PARM sparam;
1248 	uint32_t fc_edtov;	/* E_D_TOV timer value */
1249 	uint32_t fc_arbtov;	/* ARB_TOV timer value */
1250 	uint32_t fc_ratov;	/* R_A_TOV timer value */
1251 	uint32_t fc_rttov;	/* R_T_TOV timer value */
1252 	uint32_t fc_altov;	/* AL_TOV timer value */
1253 	uint32_t fc_crtov;	/* C_R_TOV timer value */
1254 	uint32_t fc_citov;	/* C_I_TOV timer value */
1255 
1256 	/* SLIM management */
1257 	uint32_t sli_mode;
1258 	MATCHMAP slim2;
1259 #ifdef SLI3_SUPPORT
1260 	/* HBQ management */
1261 	uint32_t hbq_count;	/* Total number of HBQs configured */
1262 	HBQ_INIT_t hbq_table[EMLXS_NUM_HBQ];
1263 #endif	/* SLI3_SUPPORT	 */
1264 
1265 
1266 	/* Adapter State management */
1267 	int32_t state;
1268 #define	FC_ERROR		0x01	/* Adapter shutdown */
1269 #define	FC_KILLED		0x02	/* Adapter interlocked/killed */
1270 #define	FC_WARM_START		0x03	/* Adapter reset, but not restarted */
1271 #define	FC_INIT_START		0x10	/* Adapter restarted */
1272 #define	FC_INIT_NVPARAMS	0x11
1273 #define	FC_INIT_REV		0x12
1274 #define	FC_INIT_CFGPORT		0x13
1275 #define	FC_INIT_CFGRING		0x14
1276 #define	FC_INIT_INITLINK	0x15
1277 #define	FC_LINK_DOWN		0x20
1278 #define	FC_LINK_UP		0x30
1279 #define	FC_CLEAR_LA		0x31
1280 #define	FC_READY		0x40
1281 
1282 	uint32_t flag;
1283 #define	FC_ONLINING_MODE	0x00000001
1284 #define	FC_ONLINE_MODE		0x00000002
1285 #define	FC_OFFLINING_MODE	0x00000004
1286 #define	FC_OFFLINE_MODE		0x00000008
1287 
1288 #define	FC_NPIV_ENABLED		0x00000010	/* NPIV enabled on adapter */
1289 #define	FC_NPIV_SUPPORTED	0x00000020	/* NPIV supported on fabric */
1290 #define	FC_NPIV_UNSUPPORTED	0x00000040	/* NPIV unsupported on fabric */
1291 #define	FC_NPIV_LINKUP		0x00000100	/* NPIV enabled, supported, */
1292 						/* and link is ready */
1293 #define	FC_NPIV_DELAY_REQUIRED	0x00000200	/* Delay issuing FLOGI/FDISC */
1294 						/* and NameServer cmds */
1295 
1296 #define	FC_FABRIC_ATTACHED	0x00001000
1297 #define	FC_PT_TO_PT		0x00002000
1298 #define	FC_BYPASSED_MODE	0x00004000
1299 #define	FC_MENLO_MODE		0x00008000	/* Indicates Menlo */
1300 						/* maintenance mode */
1301 
1302 #define	FC_SLIM2_MODE		0x00100000	/* SLIM in host memory */
1303 #define	FC_INTERLOCKED		0x00200000
1304 #define	FC_HBQ_ENABLED		0x00400000
1305 #define	FC_ASYNC_EVENTS		0x00800000
1306 
1307 #define	FC_ILB_MODE		0x01000000
1308 #define	FC_ELB_MODE		0x02000000
1309 #define	FC_LOOPBACK_MODE	0x03000000	/* Loopback Mode Mask */
1310 #define	FC_SHUTDOWN		0x08000000	/* SHUTDOWN in progress */
1311 
1312 #define	FC_OVERTEMP_EVENT	0x10000000	/* FC_ERROR reason: over */
1313 						/* temperature event */
1314 #define	FC_MBOX_TIMEOUT		0x20000000	/* FC_ERROR reason: mailbox */
1315 						/* timeout event */
1316 #define	FC_HARDWARE_ERROR	0x80000000	/* FC_ERROR state triggered */
1317 
1318 #define	FC_RESET_MASK		0x0000001F	/* Bits to protect during a */
1319 						/* hard reset */
1320 #define	FC_LINKDOWN_MASK	0xFFF0001F	/* Bits to protect during a */
1321 						/* linkdown */
1322 
1323 
1324 	/* Adapter memory management */
1325 	caddr_t csr_addr;
1326 	caddr_t slim_addr;
1327 	caddr_t pci_addr;
1328 	ddi_acc_handle_t csr_acc_handle;
1329 	ddi_acc_handle_t slim_acc_handle;
1330 	ddi_acc_handle_t pci_acc_handle;
1331 
1332 	/* SBUS adapter management */
1333 	caddr_t sbus_flash_addr;	/* Virt addr of R/W Flash */
1334 	caddr_t sbus_core_addr;	/* Virt addr of TITAN CORE */
1335 	caddr_t sbus_pci_addr;	/* Virt addr of TITAN pci config */
1336 	caddr_t sbus_csr_addr;	/* Virt addr of TITAN CSR */
1337 	ddi_acc_handle_t sbus_flash_acc_handle;
1338 	ddi_acc_handle_t sbus_core_acc_handle;
1339 	ddi_acc_handle_t sbus_pci_handle;
1340 	ddi_acc_handle_t sbus_csr_handle;
1341 
1342 	/* Adapter register management */
1343 	uint32_t bc_reg_addr;	/* virtual offset for BIU config reg */
1344 	uint32_t ha_reg_addr;	/* virtual offset for host attn reg */
1345 	uint32_t hc_reg_addr;	/* virtual offset for host ctl reg */
1346 	uint32_t ca_reg_addr;	/* virtual offset for FF attn reg */
1347 	uint32_t hs_reg_addr;	/* virtual offset for status reg */
1348 	uint32_t shc_reg_addr;	/* virtual offset for SBUS Ctrl reg */
1349 	uint32_t shs_reg_addr;	/* virtual offset for SBUS Status reg */
1350 	uint32_t shu_reg_addr;	/* virtual offset for SBUS Update reg */
1351 	uint16_t hgp_ring_offset;
1352 	uint16_t hgp_hbq_offset;
1353 	uint16_t iocb_cmd_size;
1354 	uint16_t iocb_rsp_size;
1355 	uint32_t hc_copy;	/* local copy of HC register */
1356 
1357 	uint32_t io_poll_count;	/* Number of poll commands */
1358 				/* in progress */
1359 
1360 	/* IO Completion management */
1361 	uint32_t iodone_count;	/* Number of IO's on done queue */
1362 	/* Protected by EMLXS_PORT_LOCK  */
1363 	emlxs_buf_t *iodone_list;	/* fc_packet being deferred */
1364 	emlxs_buf_t *iodone_tail;	/* fc_packet being deferred */
1365 	emlxs_thread_t iodone_thread;
1366 
1367 	/* Ring management */
1368 	int32_t ring_count;
1369 	emlxs_ring_t ring[MAX_RINGS];
1370 	kmutex_t ring_cmd_lock[MAX_RINGS];
1371 	uint8_t ring_masks[4];	/* number of masks/rings being used */
1372 	uint8_t ring_rval[6];
1373 	uint8_t ring_rmask[6];
1374 	uint8_t ring_tval[6];
1375 	uint8_t ring_tmask[6];
1376 
1377 	kmutex_t ring_tx_lock;
1378 	uint32_t ring_tx_count[MAX_RINGS];	/* Number of IO's on tx queue */
1379 
1380 	/* Mailbox Management */
1381 	uint32_t mbox_queue_flag;
1382 	emlxs_queue_t mbox_queue;
1383 	uint8_t *mbox_bp;	/* buffer pointer for mbox command */
1384 	uint8_t *mbox_sbp;	/* emlxs_buf_t pointer for mbox command used */
1385 				/* by reg_login only */
1386 	uint8_t *mbox_ubp;	/* fc_unsol_buf_t pointer for mbox command */
1387 				/* used by reg_login only */
1388 	uint8_t *mbox_iocbq;	/* IOCBQ pointer for mbox command. used by */
1389 				/* reg_login only */
1390 	uint8_t *mbox_mbq;	/* MBX_SLEEP context */
1391 	uint32_t mbox_mbqflag;
1392 	kcondvar_t mbox_lock_cv;	/* MBX_SLEEP */
1393 	kmutex_t mbox_lock;	/* MBX_SLEEP */
1394 	uint32_t mbox_timer;
1395 
1396 #ifdef MBOX_EXT_SUPPORT
1397 	uint8_t *mbox_ext;	/* ptr to mailbox extension buffer */
1398 	uint32_t mbox_ext_size;	/* size of mailbox extension buffer */
1399 #endif	/* MBOX_EXT_SUPPORT */
1400 
1401 	/* IOtag management */
1402 	emlxs_buf_t **iotag_table;
1403 	kmutex_t iotag_lock[MAX_RINGS];
1404 	uint32_t io_count[MAX_RINGS];	/* Number of IO's holding a regular */
1405 					/* (non-abort) iotag */
1406 	/* Protected by EMLXS_FCTAB_LOCK */
1407 #ifdef EMLXS_SPARC
1408 	MATCHMAP fcp_bpl_mp;
1409 	MATCHMAP *fcp_bpl_table;	/* iotag table for bpl buffers */
1410 #endif	/* EMLXS_SPARC */
1411 
1412 	/* Interrupt management */
1413 	void *intr_arg;
1414 	uint32_t intr_unclaimed;
1415 	uint32_t intr_autoClear;
1416 	uint32_t intr_flags;
1417 #define	EMLXS_INTX_INITED	0x0001
1418 #define	EMLXS_INTX_ADDED	0x0002
1419 #define	EMLXS_MSI_ENABLED	0x0010
1420 #define	EMLXS_MSI_INITED	0x0020
1421 #define	EMLXS_MSI_ADDED		0x0040
1422 #define	EMLXS_INTR_INITED	EMLXS_INTX_INITED|EMLXS_MSI_INITED)
1423 #define	EMLXS_INTR_ADDED	EMLXS_INTX_ADDED|EMLXS_MSI_ADDED)
1424 
1425 #ifdef MSI_SUPPORT
1426 	ddi_intr_handle_t *intr_htable;
1427 	uint32_t *intr_pri;
1428 	int32_t *intr_cap;
1429 	uint32_t intr_count;
1430 	uint32_t intr_type;
1431 	uint32_t intr_cond;
1432 	uint32_t intr_map[EMLXS_MSI_MAX_INTRS];
1433 	uint32_t intr_mask;
1434 	uint32_t msi_cap_offset;
1435 #define	MSI_CAP_ID	0x05
1436 
1437 	uint32_t msix_cap_offset;
1438 #define	MSIX_CAP_ID	0x11
1439 
1440 	kmutex_t intr_lock[EMLXS_MSI_MAX_INTRS];
1441 #endif	/* MSI_SUPPORT */
1442 
1443 	uint32_t heartbeat_timer;
1444 	uint32_t heartbeat_flag;
1445 	uint32_t heartbeat_active;
1446 
1447 	/* IOCTL management */
1448 	kmutex_t ioctl_lock;
1449 	uint32_t ioctl_flags;
1450 #define	EMLXS_OPEN		0x00000001
1451 #define	EMLXS_OPEN_EXCLUSIVE	0x00000002
1452 
1453 	/* Timer management */
1454 	kcondvar_t timer_lock_cv;
1455 	kmutex_t timer_lock;
1456 	timeout_id_t timer_id;
1457 	uint32_t timer_tics;
1458 	uint32_t timer_flags;
1459 #define	EMLXS_TIMER_STARTED	0x0000001
1460 #define	EMLXS_TIMER_BUSY	0x0000002
1461 #define	EMLXS_TIMER_KILL	0x0000004
1462 #define	EMLXS_TIMER_ENDED	0x0000008
1463 
1464 	/* Misc Timers */
1465 	uint32_t linkup_timer;
1466 	uint32_t discovery_timer;
1467 	uint32_t pkt_timer;
1468 
1469 	/* Power Management */
1470 	uint32_t pm_state;
1471 	/* pm_state */
1472 #define	EMLXS_PM_IN_ATTACH	0x00000001
1473 #define	EMLXS_PM_IN_DETACH	0x00000002
1474 #define	EMLXS_PM_IN_SOL_CB	0x00000010
1475 #define	EMLXS_PM_IN_UNSOL_CB	0x00000020
1476 #define	EMLXS_PM_IN_LINK_RESET	0x00000100
1477 #define	EMLXS_PM_IN_HARD_RESET	0x00000200
1478 #define	EMLXS_PM_SUSPENDED	0x01000000
1479 
1480 	uint32_t pm_level;
1481 	/* pm_level */
1482 #define	EMLXS_PM_ADAPTER_DOWN	0
1483 #define	EMLXS_PM_ADAPTER_UP	1
1484 
1485 	uint32_t pm_busy;
1486 	kmutex_t pm_lock;
1487 	uint8_t pm_config[PCI_CONFIG_SIZE];
1488 #ifdef IDLE_TIMER
1489 	uint32_t pm_idle_timer;
1490 	uint32_t pm_active;	/* Only used by timer */
1491 #endif	/* IDLE_TIMER */
1492 
1493 
1494 #ifdef DFC_SUPPORT
1495 	/* Loopback management */
1496 	uint32_t loopback_tics;
1497 	void *loopback_pkt;
1498 #endif	/* DFC_SUPPORT */
1499 
1500 	/* Event management */
1501 	uint32_t log_events;
1502 	emlxs_dfc_event_t dfc_event[MAX_DFC_EVENTS];
1503 	emlxs_hba_event_t hba_event;
1504 
1505 	/* Parameter management */
1506 	emlxs_config_t config[NUM_CFG_PARAM];
1507 
1508 	/* Driver stat management */
1509 	kstat_t *kstat;
1510 	emlxs_stats_t stats;
1511 
1512 	/* Log management */
1513 	emlxs_msg_log_t log;
1514 
1515 	/* Port managment */
1516 	uint32_t vpi_max;
1517 	uint32_t vpi_high;
1518 	uint32_t num_of_ports;
1519 
1520 	kmutex_t port_lock;	/* locks port, nodes, rings */
1521 	emlxs_port_t port[MAX_VPORTS + 1];	/* port specific info, the */
1522 						/* last one is for NPIV ready */
1523 						/* test */
1524 
1525 #ifdef DHCHAP_SUPPORT
1526 	kmutex_t dhc_lock;
1527 	kmutex_t auth_lock;
1528 	emlxs_auth_cfg_t auth_cfg;	/* Default auth_cfg. Points to link */
1529 					/* list of entries. Protected by */
1530 					/* auth_lock */
1531 	uint32_t auth_cfg_count;
1532 	emlxs_auth_key_t auth_key;	/* Default auth_key. Points to link */
1533 					/* list of entries. Protected by */
1534 					/* auth_lock */
1535 	uint32_t auth_key_count;
1536 	uint32_t rdn_flag;
1537 #endif	/* DHCHAP_SUPPORT */
1538 
1539 	uint16_t ini_mode;
1540 	uint16_t tgt_mode;
1541 
1542 #ifdef TEST_SUPPORT
1543 	uint32_t underrun_counter;
1544 #endif	/* TEST_SUPPORT */
1545 
1546 } emlxs_hba_t;
1547 
1548 #define	EMLXS_HBA_T	1	/* flag emlxs_hba_t is already typedefed */
1549 
1550 
1551 #ifdef MSI_SUPPORT
1552 #define	EMLXS_INTR_INIT(_hba, _m)	emlxs_msi_init(_hba, _m)
1553 #define	EMLXS_INTR_UNINIT(_hba)		emlxs_msi_uninit(_hba)
1554 #define	EMLXS_INTR_ADD(_hba)		emlxs_msi_add(_hba)
1555 #define	EMLXS_INTR_REMOVE(_hba)		emlxs_msi_remove(_hba)
1556 #else
1557 #define	EMLXS_INTR_INIT(_hba, _m)	emlxs_intx_init(_hba, _m)
1558 #define	EMLXS_INTR_UNINIT(_hba)		emlxs_intx_uninit(_hba)
1559 #define	EMLXS_INTR_ADD(_hba)		emlxs_intx_add(_hba)
1560 #define	EMLXS_INTR_REMOVE(_hba)		emlxs_intx_remove(_hba)
1561 #endif	/* MSI_SUPPORT */
1562 
1563 
1564 /* Power Management Component */
1565 #define	EMLXS_PM_ADAPTER		0
1566 
1567 
1568 #define	DRV_TIME			(uint32_t)(ddi_get_time() - \
1569 						emlxs_device.drv_timestamp)
1570 
1571 #define	HBA				port->hba
1572 #define	PPORT				hba->port[0]
1573 #define	VPORT(x)			hba->port[x]
1574 #define	EMLXS_TIMER_LOCK		hba->timer_lock
1575 #define	VPD				hba->vpd
1576 #define	CFG				hba->config[0]
1577 #define	LOG				hba->log
1578 #define	EMLXS_MBOX_LOCK			hba->mbox_lock
1579 #define	EMLXS_MBOX_CV			hba->mbox_lock_cv
1580 #define	EMLXS_LINKUP_LOCK		hba->linkup_lock
1581 #define	EMLXS_LINKUP_CV			hba->linkup_lock_cv
1582 #define	EMLXS_RINGTX_LOCK		hba->ring_tx_lock
1583 #define	EMLXS_MEMGET_LOCK		hba->memget_lock
1584 #define	EMLXS_MEMPUT_LOCK		hba->memput_lock
1585 #define	EMLXS_IOCTL_LOCK		hba->ioctl_lock	/* locks ioctl calls */
1586 #define	HBASTATS			hba->stats
1587 #define	EMLXS_CMD_RING_LOCK(n)		hba->ring_cmd_lock[n]
1588 #define	EMLXS_FCTAB_LOCK(n)		hba->iotag_lock[n]
1589 #define	EMLXS_PORT_LOCK			hba->port_lock	/* locks port, */
1590 							/* nodes, rings */
1591 #define	EMLXS_INTR_LOCK(_id)		hba->intr_lock[_id]	/* locks intr */
1592 								/* threads */
1593 
1594 #define	EMLXS_PKT_LOCK			port->pkt_lock	/* for pkt polling */
1595 #define	EMLXS_PKT_CV			port->pkt_lock_cv
1596 #define	EMLXS_UB_LOCK			port->ub_lock	/* locks unsolicited */
1597 							/* buffer pool */
1598 
1599 #ifdef EMLXS_LITTLE_ENDIAN
1600 #define	SWAP_SHORT(x)   (x)
1601 #define	SWAP_LONG(x)    (x)
1602 #define	SWAP_DATA64(x)  ((((x) & 0xFF)<<56) | (((x) & 0xFF00)<< 40) | \
1603 			(((x) & 0xFF0000)<<24) | (((x) & 0xFF000000)<<8) | \
1604 			(((x) & 0xFF00000000)>>8) | \
1605 			(((x) & 0xFF0000000000)>>24) | \
1606 			(((x) & 0xFF000000000000)>>40) | \
1607 			(((x) & 0xFF00000000000000)>>56))
1608 #define	SWAP_DATA32(x)	((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \
1609 			(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
1610 #define	SWAP_DATA16(x)  ((((x) & 0xFF) << 8) | ((x) >> 8))
1611 #define	PCIMEM_SHORT(x) SWAP_SHORT(x)
1612 #define	PCIMEM_LONG(x)  SWAP_LONG(x)
1613 #define	PCIMEM_DATA(x)  SWAP_DATA32(x)
1614 
1615 
1616 #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1617 #define	SWAP_DATA24_LO(x)    (x)
1618 #define	SWAP_DATA24_HI(x)    (x)
1619 #endif	/* EMLXS_MODREV2X */
1620 
1621 #if (EMLXS_MODREVX == EMLXS_MODREV3X)
1622 #define	SWAP_DATA24_LO(x)    ((((x) & 0xFF)<<16) | ((x) & 0xFF00FF00) | \
1623 					(((x) & 0x00FF0000)>>16))
1624 #define	SWAP_DATA24_HI(x)    (((x) & 0x00FF00FF) | (((x) & 0x0000FF00)<<16) | \
1625 					(((x) & 0xFF000000)>>16))
1626 #endif	/* EMLXS_MODREV3X */
1627 
1628 #endif	/* EMLXS_LITTLE_ENDIAN */
1629 
1630 
1631 
1632 #ifdef EMLXS_BIG_ENDIAN
1633 
1634 #define	SWAP_SHORT(x)   ((((x) & 0xFF) << 8) | ((x) >> 8))
1635 #define	SWAP_LONG(x)    ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \
1636 			(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
1637 
1638 #define	SWAP_DATA64(x)		(x)
1639 #define	SWAP_DATA32(x)		(x)
1640 #define	SWAP_DATA16(x)		(x)
1641 
1642 #define	PCIMEM_SHORT(x)		SWAP_SHORT(x)
1643 #define	PCIMEM_LONG(x)		SWAP_LONG(x)
1644 #define	PCIMEM_DATA(x)		SWAP_DATA32(x)
1645 
1646 #define	SWAP_DATA24_LO(x)	(x)
1647 #define	SWAP_DATA24_HI(x)	(x)
1648 
1649 #endif	/* EMLXS_BIG_ENDIAN */
1650 
1651 #define	SWAP_ALWAYS(x)  ((((x) & 0xFF)<<24) | (((x) & 0xFF00)<<8) | \
1652 			(((x) & 0xFF0000)>>8) | (((x) & 0xFF000000)>>24))
1653 #define	SWAP_ALWAYS16(x) ((((x) & 0xFF) << 8) | ((x) >> 8))
1654 
1655 /*
1656  * For PCI configuration
1657  */
1658 #define	ADDR_LO(addr)   ((int)(addr) & 0xffff)	/* low 16 bits */
1659 #define	ADDR_HI(addr)   (((int)(addr) >> 16) & 0xffff)	/* high 16 bits */
1660 
1661 #ifdef	__cplusplus
1662 }
1663 #endif
1664 
1665 #endif	/* _EMLXS_FC_H */
1666