emlxs_fc.h revision 93c20f2609342fd05f6625f16dfcb9348e7977f2
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
32extern "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
72typedef 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
201typedef 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
258typedef 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;
265typedef 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 */
273typedef 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;
296typedef 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 */
319typedef 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;
355typedef emlxs_ring_t RING;
356
357
358typedef 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;
405typedef emlxs_node_t NODELIST;
406
407
408
409#define	NADDR_LEN	6	/* MAC network address length */
410typedef 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;
415typedef 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
463typedef 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;
484typedef 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 */
494typedef 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
621typedef 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
633typedef 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
865typedef 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
907typedef 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
1156typedef 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;
1195extern 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
1209typedef 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