qlt.h revision 10422:d943e7451c42
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2009 QLogic Corporation.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*
28 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
29 * Use is subject to license terms.
30 */
31
32#ifndef	_QLT_H
33#define	_QLT_H
34
35#include <stmf_defines.h>
36#include <qlt_regs.h>
37
38#ifdef	__cplusplus
39extern "C" {
40#endif
41
42/*
43 * Qlogic logging
44 */
45extern int enable_extended_logging;
46
47/*
48 * Caution: 1) LOG will be available in debug/non-debug mode
49 *	    2) Anything which can potentially flood the log should be under
50 *	       extended logging, and use QLT_EXT_LOG.
51 *	    3) Don't use QLT_EXT_LOG in performance-critical code path, such
52 *	       as normal SCSI I/O code path. It could hurt system performance.
53 *	    4) Use kmdb to change enable_extened_logging in the fly to adjust
54 *	       tracing
55 */
56#define	QLT_EXT_LOG(log_ident, ...)	\
57		if (enable_extended_logging) {	\
58			stmf_trace(log_ident, __VA_ARGS__);	\
59		}
60
61#define	QLT_LOG(log_ident, ...)	\
62	stmf_trace(log_ident, __VA_ARGS__)
63
64/*
65 * Error codes. FSC stands for Failure sub code.
66 */
67#define	QLT_FAILURE			FCT_FCA_FAILURE
68#define	QLT_SUCCESS			FCT_SUCCESS
69#define	QLT_FSC(x)			((uint64_t)(x) << 40)
70#define	QLT_DMA_STUCK			(QLT_FAILURE | QLT_FSC(1))
71#define	QLT_MAILBOX_STUCK		(QLT_FAILURE | QLT_FSC(2))
72#define	QLT_ROM_STUCK			(QLT_FAILURE | QLT_FSC(3))
73#define	QLT_UNEXPECTED_RESPONSE		(QLT_FAILURE | QLT_FSC(4))
74#define	QLT_MBOX_FAILED			(QLT_FAILURE | QLT_FSC(5))
75#define	QLT_MBOX_NOT_INITIALIZED	(QLT_FAILURE | QLT_FSC(6))
76#define	QLT_MBOX_BUSY			(QLT_FAILURE | QLT_FSC(7))
77#define	QLT_MBOX_ABORTED		(QLT_FAILURE | QLT_FSC(8))
78#define	QLT_MBOX_TIMEOUT		(QLT_FAILURE | QLT_FSC(9))
79#define	QLT_RESP_TIMEOUT		(QLT_FAILURE | QLT_FSC(10))
80#define	QLT_FLASH_TIMEOUT		(QLT_FAILURE | QLT_FSC(11))
81#define	QLT_FLASH_ACCESS_ERROR		(QLT_FAILURE | QLT_FSC(12))
82#define	QLT_BAD_NVRAM_DATA		(QLT_FAILURE | QLT_FSC(13))
83#define	QLT_FIRMWARE_ERROR_CODE		(QLT_FAILURE | QLT_FSC(14))
84
85#define	QLT_FIRMWARE_ERROR(s, c1, c2)	(QLT_FIRMWARE_ERROR_CODE | \
86	(((uint64_t)s) << 32) | (((uint64_t)c1) << 24) | ((uint64_t)c2))
87
88extern uint32_t fw2400_code01[];
89extern uint32_t fw2400_length01;
90extern uint32_t fw2400_addr01;
91extern uint32_t fw2400_code02[];
92extern uint32_t fw2400_length02;
93extern uint32_t fw2400_addr02;
94
95extern uint32_t fw2500_code01[];
96extern uint32_t fw2500_length01;
97extern uint32_t fw2500_addr01;
98extern uint32_t fw2500_code02[];
99extern uint32_t fw2500_length02;
100extern uint32_t fw2500_addr02;
101
102extern uint32_t fw8100_code01[];
103extern uint32_t fw8100_length01;
104extern uint32_t fw8100_addr01;
105extern uint32_t fw8100_code02[];
106extern uint32_t fw8100_length02;
107extern uint32_t fw8100_addr02;
108
109typedef enum {
110	MBOX_STATE_UNKNOWN = 0,
111	MBOX_STATE_READY,
112	MBOX_STATE_CMD_RUNNING,
113	MBOX_STATE_CMD_DONE
114} mbox_state_t;
115
116#define	IOCB_SIZE		64
117
118/*
119 * These should not be constents but should be obtained from fw.
120 */
121#define	QLT_MAX_LOGINS	2048
122#define	QLT_MAX_XCHGES	2048
123
124#define	MAX_MBOXES	32
125#define	MBOX_TIMEOUT	(2*1000*1000)
126#define	DEREG_RP_TIMEOUT	(2*1000*1000)
127
128typedef struct {
129	uint16_t	to_fw[MAX_MBOXES];
130	uint32_t	to_fw_mask;
131	uint16_t	from_fw[MAX_MBOXES];
132	uint32_t	from_fw_mask;
133	stmf_data_buf_t *dbuf;
134} mbox_cmd_t;
135
136typedef struct qlt_abts_cmd {
137	uint8_t		buf[IOCB_SIZE];
138} qlt_abts_cmd_t;
139
140struct qlt_dmem_bucket;
141
142#define	QLT_INTR_FIXED	0x1
143#define	QLT_INTR_MSI	0x2
144#define	QLT_INTR_MSIX	0x4
145
146typedef struct qlt_el_trace_desc {
147	kmutex_t	mutex;
148	uint16_t	next;
149	uint32_t	trace_buffer_size;
150	char		*trace_buffer;
151} qlt_el_trace_desc_t;
152
153typedef struct qlt_state {
154	dev_info_t		*dip;
155	char			qlt_minor_name[16];
156	char			qlt_port_alias[16];
157	fct_local_port_t	*qlt_port;
158	struct qlt_dmem_bucket	**dmem_buckets;
159
160	int			instance;
161	uint8_t			qlt_state:7,
162				qlt_state_not_acked:1;
163	uint8_t			qlt_intr_enabled:1,
164				qlt_25xx_chip:1,
165				qlt_stay_offline:1,
166				qlt_link_up,
167				qlt_81xx_chip:1,
168				qlt_rsvd1:3;
169	uint8_t			cur_topology;
170
171	/* Registers */
172	caddr_t		regs;
173	ddi_acc_handle_t regs_acc_handle;
174	ddi_acc_handle_t pcicfg_acc_handle;
175
176	/* Interrupt stuff */
177	kmutex_t		intr_lock;	/* Only used by intr routine */
178	int			intr_sneak_counter;
179	ddi_intr_handle_t	*htable;
180	int			intr_size;
181	int			intr_cnt;
182	uint_t			intr_pri;
183	int			intr_cap;
184	int			intr_flags;
185
186	/* Queues */
187	ddi_dma_handle_t queue_mem_dma_handle;
188	ddi_acc_handle_t queue_mem_acc_handle;
189	caddr_t		 queue_mem_ptr;
190	ddi_dma_cookie_t queue_mem_cookie;
191
192	kmutex_t	req_lock;
193	caddr_t		req_ptr;
194	uint32_t	req_ndx_to_fw;
195	uint32_t	req_ndx_from_fw;
196	uint32_t	req_available;
197
198	caddr_t		resp_ptr;
199	uint32_t	resp_ndx_to_fw;
200	uint32_t	resp_ndx_from_fw;
201
202	kmutex_t	preq_lock;
203	caddr_t		preq_ptr;
204	uint32_t	preq_ndx_to_fw;
205	uint32_t	preq_ndx_from_fw;
206
207	kcondvar_t	rp_dereg_cv; /* for deregister cmd */
208	uint32_t	rp_id_in_dereg; /* remote port in deregistering */
209	fct_status_t	rp_dereg_status;
210
211	caddr_t		atio_ptr;
212	uint16_t	atio_ndx_to_fw;
213	uint16_t	atio_ndx_from_fw;
214
215	kmutex_t	dma_mem_lock;
216
217	/* MailBox data */
218	kmutex_t	mbox_lock;
219	kcondvar_t	mbox_cv;
220	mbox_state_t	mbox_io_state;
221	mbox_cmd_t	*mcp;
222	qlt_nvram_t	*nvram;
223
224	uint8_t		link_speed;	/* Cached from intr routine */
225	uint16_t	fw_major;
226	uint16_t	fw_minor;
227	uint16_t	fw_subminor;
228	uint16_t	fw_endaddrlo;
229	uint16_t	fw_endaddrhi;
230	uint16_t	fw_attr;
231
232	uint32_t	fw_addr01;
233	uint32_t	fw_length01;
234	uint32_t	*fw_code01;
235	uint32_t	fw_addr02;
236	uint32_t	fw_length02;
237	uint32_t	*fw_code02;
238
239	uint32_t	qlt_ioctl_flags;
240	kmutex_t	qlt_ioctl_lock;
241	caddr_t		qlt_fwdump_buf;	/* FWDUMP will use ioctl flags/lock */
242	uint32_t	qlt_change_state_flags;	/* Cached for ACK handling */
243
244	qlt_el_trace_desc_t	*el_trace_desc;
245} qlt_state_t;
246
247/*
248 * FWDUMP flags (part of IOCTL flags)
249 */
250#define	QLT_FWDUMP_INPROGRESS		0x0100	/* if it's dumping now */
251#define	QLT_FWDUMP_TRIGGERED_BY_USER	0x0200	/* if users triggered it */
252#define	QLT_FWDUMP_FETCHED_BY_USER	0x0400	/* if users have viewed it */
253#define	QLT_FWDUMP_ISVALID		0x0800
254
255/*
256 * IOCTL supporting stuff
257 */
258#define	QLT_IOCTL_FLAG_MASK		0xFF
259#define	QLT_IOCTL_FLAG_IDLE		0x00
260#define	QLT_IOCTL_FLAG_OPEN		0x01
261#define	QLT_IOCTL_FLAG_EXCL		0x02
262
263typedef struct qlt_cmd {
264	stmf_data_buf_t	*dbuf;		/* dbuf with handle 0 for SCSI cmds */
265	stmf_data_buf_t	*dbuf_rsp_iu;	/* dbuf for possible FCP_RSP IU */
266	uint32_t	fw_xchg_addr;
267	uint16_t	flags;
268	union {
269		uint16_t	resp_offset;
270		uint8_t		atio_byte3;
271	} param;
272} qlt_cmd_t;
273
274/*
275 * cmd flags
276 */
277#define	QLT_CMD_ABORTING		1
278#define	QLT_CMD_ABORTED			2
279#define	QLT_CMD_TYPE_SOLICITED		4
280
281typedef struct {
282	int	dummy;
283} qlt_remote_port_t;
284
285#define	REQUEST_QUEUE_ENTRIES	2048
286#define	RESPONSE_QUEUE_ENTRIES	2048
287#define	ATIO_QUEUE_ENTRIES	2048
288#define	PRIORITY_QUEUE_ENTRIES	128
289
290#define	REQUEST_QUEUE_OFFSET	0
291#define	RESPONSE_QUEUE_OFFSET	(REQUEST_QUEUE_OFFSET + \
292				    (REQUEST_QUEUE_ENTRIES * IOCB_SIZE))
293#define	ATIO_QUEUE_OFFSET	(RESPONSE_QUEUE_OFFSET + \
294				    (RESPONSE_QUEUE_ENTRIES * IOCB_SIZE))
295#define	PRIORITY_QUEUE_OFFSET	(ATIO_QUEUE_OFFSET + \
296				    (ATIO_QUEUE_ENTRIES * IOCB_SIZE))
297#define	MBOX_DMA_MEM_SIZE	4096
298#define	MBOX_DMA_MEM_OFFSET		(PRIORITY_QUEUE_OFFSET + \
299				    (PRIORITY_QUEUE_ENTRIES * IOCB_SIZE))
300#define	TOTAL_DMA_MEM_SIZE	(MBOX_DMA_MEM_OFFSET + MBOX_DMA_MEM_SIZE)
301
302#define	QLT_MAX_ITERATIONS_PER_INTR	32
303
304#define	REG_RD16(qlt, addr) \
305	ddi_get16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr))
306#define	REG_RD32(qlt, addr) \
307	ddi_get32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr))
308#define	REG_WR16(qlt, addr, data) \
309	ddi_put16(qlt->regs_acc_handle, (uint16_t *)(qlt->regs + addr), \
310	(uint16_t)(data))
311#define	REG_WR32(qlt, addr, data) \
312	ddi_put32(qlt->regs_acc_handle, (uint32_t *)(qlt->regs + addr), \
313	(uint32_t)(data))
314#define	PCICFG_RD16(qlt, addr) \
315	pci_config_get16(qlt->pcicfg_acc_handle, (off_t)(addr))
316#define	PCICFG_RD32(qlt, addr) \
317	pci_config_get32(qlt->pcicfg_acc_handle, (off_t)(addr))
318#define	PCICFG_WR16(qlt, addr, data) \
319	pci_config_put16(qlt->pcicfg_acc_handle, (off_t)(addr), \
320		(uint16_t)(data))
321#define	QMEM_RD16(qlt, addr) \
322	ddi_get16(qlt->queue_mem_acc_handle, (uint16_t *)(addr))
323#define	DMEM_RD16(qlt, addr) LE_16((uint16_t)(*((uint16_t *)(addr))))
324#define	QMEM_RD32(qlt, addr) \
325	ddi_get32(qlt->queue_mem_acc_handle, (uint32_t *)(addr))
326#define	DMEM_RD32(qlt, addr) LE_32((uint32_t)(*((uint32_t *)(addr))))
327/*
328 * #define	QMEM_RD64(qlt, addr) \
329 *	ddi_get64(qlt->queue_mem_acc_handle, (uint64_t *)(addr))
330 */
331#define	QMEM_WR16(qlt, addr, data) \
332	ddi_put16(qlt->queue_mem_acc_handle, (uint16_t *)(addr), \
333	(uint16_t)(data))
334#define	DMEM_WR16(qlt, addr, data) (*((uint16_t *)(addr)) = \
335	(uint16_t)LE_16((uint16_t)(data)))
336#define	QMEM_WR32(qlt, addr, data) \
337	ddi_put32(qlt->queue_mem_acc_handle, (uint32_t *)(addr), \
338	(uint32_t)(data))
339#define	DMEM_WR32(qlt, addr, data) (*((uint32_t *)(addr)) = \
340						LE_32((uint32_t)(data)))
341
342/*
343 * [QD]MEM is always little endian so the [QD]MEM_WR64 macro works for
344 * both sparc and x86.
345 */
346#define	QMEM_WR64(qlt, addr, data) \
347	QMEM_WR32(qlt, addr, (data & 0xffffffff)), \
348	QMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32)
349
350#define	DMEM_WR64(qlt, addr, data) \
351	DMEM_WR32(qlt, addr, (data & 0xffffffff)), \
352	DMEM_WR32(qlt, (addr)+4, ((uint64_t)data) >> 32)
353
354void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...);
355void qlt_dump_el_trace_buffer(qlt_state_t *qlt);
356#define	EL(qlt, ...) 	qlt_el_msg(qlt, __func__, CE_CONT, __VA_ARGS__);
357#define	EL_TRACE_BUF_SIZE	8192
358#define	EL_BUFFER_RESERVE	256
359#define	DEBUG_STK_DEPTH		24
360#define	EL_TRACE_BUF_SIZE	8192
361
362#ifdef	__cplusplus
363}
364#endif
365
366#endif /* _QLT_H */
367