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
39 extern "C" {
40 #endif
41 
42 /*
43  * Qlogic logging
44  */
45 extern 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 
88 extern uint32_t fw2400_code01[];
89 extern uint32_t fw2400_length01;
90 extern uint32_t fw2400_addr01;
91 extern uint32_t fw2400_code02[];
92 extern uint32_t fw2400_length02;
93 extern uint32_t fw2400_addr02;
94 
95 extern uint32_t fw2500_code01[];
96 extern uint32_t fw2500_length01;
97 extern uint32_t fw2500_addr01;
98 extern uint32_t fw2500_code02[];
99 extern uint32_t fw2500_length02;
100 extern uint32_t fw2500_addr02;
101 
102 extern uint32_t fw8100_code01[];
103 extern uint32_t fw8100_length01;
104 extern uint32_t fw8100_addr01;
105 extern uint32_t fw8100_code02[];
106 extern uint32_t fw8100_length02;
107 extern uint32_t fw8100_addr02;
108 
109 typedef 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 
128 typedef 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 
136 typedef struct qlt_abts_cmd {
137 	uint8_t		buf[IOCB_SIZE];
138 } qlt_abts_cmd_t;
139 
140 struct qlt_dmem_bucket;
141 
142 #define	QLT_INTR_FIXED	0x1
143 #define	QLT_INTR_MSI	0x2
144 #define	QLT_INTR_MSIX	0x4
145 
146 typedef 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 
153 typedef 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 
263 typedef 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 
281 typedef 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 
354 /*
355  * Structure used to associate values with strings which describe them.
356  */
357 typedef struct string_table_entry {
358 	uint32_t value;
359 	char    *string;
360 } string_table_t;
361 
362 char *prop_text(int prop_status);
363 char *value2string(string_table_t *entry, int value, int delimiter);
364 
365 #define	PROP_STATUS_DELIMITER	((uint32_t)0xFFFF)
366 
367 #define	DDI_PROP_STATUS()					\
368 {								\
369 	{DDI_PROP_SUCCESS, "DDI_PROP_SUCCESS"},			\
370 	{DDI_PROP_NOT_FOUND, "DDI_PROP_NOT_FOUND"},		\
371 	{DDI_PROP_UNDEFINED, "DDI_PROP_UNDEFINED"},		\
372 	{DDI_PROP_NO_MEMORY, "DDI_PROP_NO_MEMORY"},		\
373 	{DDI_PROP_INVAL_ARG, "DDI_PROP_INVAL_ARG"},		\
374 	{DDI_PROP_BUF_TOO_SMALL, "DDI_PROP_BUF_TOO_SMALL"},	\
375 	{DDI_PROP_CANNOT_DECODE, "DDI_PROP_CANNOT_DECODE"},	\
376 	{DDI_PROP_CANNOT_ENCODE, "DDI_PROP_CANNOT_ENCODE"},	\
377 	{DDI_PROP_END_OF_DATA, "DDI_PROP_END_OF_DATA"},		\
378 	{PROP_STATUS_DELIMITER, "DDI_PROP_UNKNOWN"}		\
379 }
380 
381 #ifndef TRUE
382 #define	TRUE	B_TRUE
383 #endif
384 
385 #ifndef FALSE
386 #define	FALSE	B_FALSE
387 #endif
388 
389 /* Little endian machine correction defines. */
390 #ifdef _LITTLE_ENDIAN
391 #define	LITTLE_ENDIAN_16(x)
392 #define	LITTLE_ENDIAN_24(x)
393 #define	LITTLE_ENDIAN_32(x)
394 #define	LITTLE_ENDIAN_64(x)
395 #define	LITTLE_ENDIAN(bp, bytes)
396 #define	BIG_ENDIAN_16(x)	qlt_chg_endian((uint8_t *)x, 2)
397 #define	BIG_ENDIAN_24(x)	qlt_chg_endian((uint8_t *)x, 3)
398 #define	BIG_ENDIAN_32(x)	qlt_chg_endian((uint8_t *)x, 4)
399 #define	BIG_ENDIAN_64(x)	qlt_chg_endian((uint8_t *)x, 8)
400 #define	BIG_ENDIAN(bp, bytes)	qlt_chg_endian((uint8_t *)bp, bytes)
401 #endif /* _LITTLE_ENDIAN */
402 
403 /* Big endian machine correction defines. */
404 #ifdef _BIG_ENDIAN
405 #define	LITTLE_ENDIAN_16(x)		qlt_chg_endian((uint8_t *)x, 2)
406 #define	LITTLE_ENDIAN_24(x)		qlt_chg_endian((uint8_t *)x, 3)
407 #define	LITTLE_ENDIAN_32(x)		qlt_chg_endian((uint8_t *)x, 4)
408 #define	LITTLE_ENDIAN_64(x)		qlt_chg_endian((uint8_t *)x, 8)
409 #define	LITTLE_ENDIAN(bp, bytes)	qlt_chg_endian((uint8_t *)bp, bytes)
410 #define	BIG_ENDIAN_16(x)
411 #define	BIG_ENDIAN_24(x)
412 #define	BIG_ENDIAN_32(x)
413 #define	BIG_ENDIAN_64(x)
414 #define	BIG_ENDIAN(bp, bytes)
415 #endif /* _BIG_ENDIAN */
416 
417 void	qlt_chg_endian(uint8_t *, size_t);
418 
419 void qlt_el_msg(qlt_state_t *qlt, const char *fn, int ce, ...);
420 void qlt_dump_el_trace_buffer(qlt_state_t *qlt);
421 #define	EL(qlt, ...) 	qlt_el_msg(qlt, __func__, CE_CONT, __VA_ARGS__);
422 #define	EL_TRACE_BUF_SIZE	8192
423 #define	EL_BUFFER_RESERVE	256
424 #define	DEBUG_STK_DEPTH		24
425 #define	EL_TRACE_BUF_SIZE	8192
426 
427 #ifdef	__cplusplus
428 }
429 #endif
430 
431 #endif /* _QLT_H */
432