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 /* Copyright 2009 QLogic Corporation */
23 
24 /*
25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2009 QLogic Corporation; ql_mbx.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_iocb.h>
48 #include <ql_isr.h>
49 #include <ql_mbx.h>
50 #include <ql_xioctl.h>
51 
52 /*
53  * Local data
54  */
55 
56 /*
57  * Local prototypes
58  */
59 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
60 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint16_t,
61     uint32_t, uint16_t);
62 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
63 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
64     caddr_t, uint32_t);
65 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
66     uint32_t);
67 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
68 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
69 
70 /*
71  * ql_mailbox_command
72  *	Issue mailbox command and waits for completion.
73  *
74  * Input:
75  *	ha = adapter state pointer.
76  *	mcp = mailbox command parameter structure pointer.
77  *
78  * Returns:
79  *	ql local function return status code.
80  *
81  * Context:
82  *	Kernel context.
83  */
84 static int
85 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
86 {
87 	uint16_t		cnt;
88 	uint32_t		data;
89 	clock_t			timer, cv_stat;
90 	int			rval;
91 	uint32_t		set_flags = 0;
92 	uint32_t		reset_flags = 0;
93 	ql_adapter_state_t	*ha = vha->pha;
94 	int			mbx_cmd = mcp->mb[0];
95 
96 	ASSERT(!MUTEX_HELD(&ha->mutex));
97 
98 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
99 
100 	/* Acquire mailbox register lock. */
101 	MBX_REGISTER_LOCK(ha);
102 
103 	/* Check for mailbox available, if not wait for signal. */
104 	while (ha->mailbox_flags & MBX_BUSY_FLG) {
105 		ha->mailbox_flags = (uint8_t)
106 		    (ha->mailbox_flags | MBX_WANT_FLG);
107 
108 		if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
109 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
110 			MBX_REGISTER_UNLOCK(ha);
111 			return (QL_LOCK_TIMEOUT);
112 		}
113 
114 		/* Set timeout after command that is running. */
115 		timer = ddi_get_lbolt();
116 		timer += (mcp->timeout + 20) * drv_usectohz(1000000);
117 		cv_stat = cv_timedwait_sig(&ha->cv_mbx_wait,
118 		    &ha->pha->mbx_mutex, timer);
119 		if (cv_stat == -1 || cv_stat == 0) {
120 			/*
121 			 * The timeout time 'timer' was
122 			 * reached without the condition
123 			 * being signaled.
124 			 */
125 			ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
126 			    ~MBX_WANT_FLG);
127 			cv_broadcast(&ha->cv_mbx_wait);
128 
129 			/* Release mailbox register lock. */
130 			MBX_REGISTER_UNLOCK(ha);
131 
132 			if (cv_stat == 0) {
133 				EL(vha, "waiting for availability aborted, "
134 				    "cmd=%xh\n", mcp->mb[0]);
135 				return (QL_ABORTED);
136 			}
137 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
138 			return (QL_LOCK_TIMEOUT);
139 		}
140 	}
141 
142 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
143 
144 	/* Structure pointer for return mailbox registers. */
145 	ha->mcp = mcp;
146 
147 	/* Load mailbox registers. */
148 	data = mcp->out_mb;
149 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
150 		if (data & MBX_0) {
151 			WRT16_IO_REG(ha, mailbox[cnt], mcp->mb[cnt]);
152 		}
153 		data >>= 1;
154 	}
155 
156 	/* Issue set host interrupt command. */
157 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
158 	CFG_IST(ha, CFG_CTRL_2425) ?
159 	    WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT) :
160 	    WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
161 
162 	/* Wait for command to complete. */
163 	if (ha->flags & INTERRUPTS_ENABLED &&
164 	    !(ha->task_daemon_flags & (TASK_THREAD_CALLED |
165 	    TASK_DAEMON_POWERING_DOWN)) &&
166 	    !ddi_in_panic()) {
167 		while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
168 		    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
169 
170 			/* 30 seconds from now */
171 			timer = ddi_get_lbolt();
172 			timer += mcp->timeout * drv_usectohz(1000000);
173 			if (cv_timedwait(&ha->cv_mbx_intr, &ha->pha->mbx_mutex,
174 			    timer) == -1) {
175 				/*
176 				 * The timeout time 'timer' was
177 				 * reached without the condition
178 				 * being signaled.
179 				 */
180 				break;
181 			}
182 		}
183 	} else {
184 		/* Release mailbox register lock. */
185 		MBX_REGISTER_UNLOCK(ha);
186 
187 		/* Acquire interrupt lock. */
188 		for (timer = mcp->timeout * 100; timer; timer--) {
189 			/* Check for pending interrupts. */
190 			while (RD16_IO_REG(ha, istatus) & RISC_INT) {
191 				(void) ql_isr((caddr_t)ha);
192 				INTR_LOCK(ha);
193 				ha->intr_claimed = B_TRUE;
194 				INTR_UNLOCK(ha);
195 				if (ha->mailbox_flags &
196 				    (MBX_INTERRUPT | MBX_ABORT) ||
197 				    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
198 					break;
199 				}
200 			}
201 			if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
202 			    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
203 				break;
204 			} else if (!ddi_in_panic() && timer % 101 == 0) {
205 				delay(drv_usectohz(10000));
206 			} else {
207 				drv_usecwait(10000);
208 			}
209 		}
210 
211 		/* Acquire mailbox register lock. */
212 		MBX_REGISTER_LOCK(ha);
213 	}
214 
215 	/* Mailbox command timeout? */
216 	if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
217 	    ha->mailbox_flags & MBX_ABORT) {
218 		rval = QL_ABORTED;
219 	} else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
220 		if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
221 			(void) ql_binary_fw_dump(ha, FALSE);
222 		}
223 		EL(vha, "command timeout, isp_abort_needed\n");
224 		set_flags |= ISP_ABORT_NEEDED;
225 		rval = QL_FUNCTION_TIMEOUT;
226 	} else {
227 		ha->mailbox_flags = (uint8_t)
228 		    (ha->mailbox_flags & ~MBX_INTERRUPT);
229 		/*
230 		 * This is the expected completion path so
231 		 * return the actual mbx cmd completion status.
232 		 */
233 		rval = mcp->mb[0];
234 	}
235 
236 	/*
237 	 * Clear outbound to risc mailbox registers per spec. The exception
238 	 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
239 	 * so avoid writing them.
240 	 */
241 	if (ha->cfg_flags & CFG_CTRL_2200) {
242 		data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
243 	} else {
244 		data = (mcp->out_mb >> 1);
245 	}
246 	for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
247 		if (data & MBX_0) {
248 			WRT16_IO_REG(ha, mailbox[cnt], (uint16_t)0);
249 		}
250 		data >>= 1;
251 	}
252 
253 	/* Reset busy status. */
254 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
255 	    ~(MBX_BUSY_FLG | MBX_ABORT));
256 	ha->mcp = NULL;
257 
258 	/* If thread is waiting for mailbox go signal it to start. */
259 	if (ha->mailbox_flags & MBX_WANT_FLG) {
260 		ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
261 		    ~MBX_WANT_FLG);
262 		cv_broadcast(&ha->cv_mbx_wait);
263 	}
264 
265 	/* Release mailbox register lock. */
266 	MBX_REGISTER_UNLOCK(ha);
267 
268 	if (set_flags != 0 || reset_flags != 0) {
269 		ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
270 	}
271 
272 	if (rval != QL_SUCCESS) {
273 		EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
274 		    mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
275 	} else {
276 		/*EMPTY*/
277 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
278 	}
279 
280 	return (rval);
281 }
282 
283 /*
284  * ql_setup_mbox_dma_resources
285  *	Prepare the data for a mailbox dma transfer.
286  *
287  * Input:
288  *	ha = adapter state pointer.
289  *	mem_desc = descriptor to contain the dma resource information.
290  *	data = pointer to the data.
291  *	size = size of the data in bytes.
292  *
293  * Returns:
294  *	ql local function return status code.
295  *
296  * Context:
297  *	Kernel context.
298  */
299 static int
300 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
301     caddr_t data, uint32_t size)
302 {
303 	int rval = QL_SUCCESS;
304 
305 	if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) ==
306 	    QL_SUCCESS) {
307 		ql_setup_mbox_dma_data(mem_desc, data);
308 	} else {
309 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
310 	}
311 
312 	return (rval);
313 }
314 
315 /*
316  * ql_setup_mbox_dma_resources
317  *	Prepare a dma buffer.
318  *
319  * Input:
320  *	ha = adapter state pointer.
321  *	mem_desc = descriptor to contain the dma resource information.
322  *	data = pointer to the data.
323  *	size = size of the data in bytes.
324  *
325  * Returns:
326  *	ql local function return status code.
327  *
328  * Context:
329  *	Kernel context.
330  */
331 static int
332 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
333     uint32_t size)
334 {
335 	int	rval = QL_SUCCESS;
336 
337 	if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA,
338 	    QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
339 		EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n");
340 		rval = QL_MEMORY_ALLOC_FAILED;
341 	}
342 
343 	return (rval);
344 }
345 
346 /*
347  * ql_setup_mbox_dma_data
348  *	Move data to the dma buffer.
349  *
350  * Input:
351  *	mem_desc = descriptor to contain the dma resource information.
352  *	data = pointer to the data.
353  *
354  * Returns:
355  *
356  * Context:
357  *	Kernel context.
358  */
359 static void
360 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
361 {
362 	/* Copy out going data to DMA buffer. */
363 	ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data,
364 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
365 
366 	/* Sync DMA buffer. */
367 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
368 	    DDI_DMA_SYNC_FORDEV);
369 }
370 
371 /*
372  * ql_get_mbox_dma_data
373  *	Recover data from the dma buffer.
374  *
375  * Input:
376  *	mem_desc = descriptor to contain the dma resource information.
377  *	data = pointer to the data.
378  *
379  * Returns:
380  *
381  * Context:
382  *	Kernel context.
383  */
384 static void
385 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
386 {
387 	/* Sync in coming DMA buffer. */
388 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
389 	    DDI_DMA_SYNC_FORKERNEL);
390 	/* Copy in coming DMA data. */
391 	ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data,
392 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
393 }
394 
395 /*
396  * ql_initialize_ip
397  *	Initialize IP receive buffer queue.
398  *
399  * Input:
400  *	ha = adapter state pointer.
401  *	ha->ip_init_ctrl_blk = setup for transmit.
402  *
403  * Returns:
404  *	ql local function return status code.
405  *
406  * Context:
407  *	Kernel context.
408  */
409 int
410 ql_initialize_ip(ql_adapter_state_t *ha)
411 {
412 	ql_link_t	*link;
413 	ql_tgt_t	*tq;
414 	uint16_t	index;
415 	int		rval;
416 	dma_mem_t	mem_desc;
417 	mbx_cmd_t	mc = {0};
418 	mbx_cmd_t	*mcp = &mc;
419 
420 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
421 
422 	if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_25XX)) ||
423 	    ha->vp_index != 0) {
424 		ha->flags &= ~IP_INITIALIZED;
425 		EL(ha, "HBA does not support IP\n");
426 		return (QL_FUNCTION_FAILED);
427 	}
428 
429 	ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
430 	ha->rcvbuf_ring_index = 0;
431 
432 	/* Reset all sequence counts. */
433 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
434 		for (link = ha->dev[index].first; link != NULL;
435 		    link = link->next) {
436 			tq = link->base_address;
437 			tq->ub_total_seg_cnt = 0;
438 		}
439 	}
440 
441 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
442 	    (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
443 	if (rval != QL_SUCCESS) {
444 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
445 		return (rval);
446 	}
447 
448 	mcp->mb[0] = MBC_INITIALIZE_IP;
449 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
450 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
451 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
452 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
453 	mcp->mb[8] = 0;
454 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
455 	mcp->in_mb = MBX_8|MBX_0;
456 	mcp->timeout = MAILBOX_TOV;
457 	rval = ql_mailbox_command(ha, mcp);
458 
459 	ql_free_dma_resource(ha, &mem_desc);
460 
461 	if (rval == QL_SUCCESS) {
462 		ADAPTER_STATE_LOCK(ha);
463 		ha->flags |= IP_INITIALIZED;
464 		ADAPTER_STATE_UNLOCK(ha);
465 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
466 	} else {
467 		ha->flags &= ~IP_INITIALIZED;
468 		EL(ha, "failed, rval = %xh\n", rval);
469 	}
470 	return (rval);
471 }
472 
473 /*
474  * ql_shutdown_ip
475  *	Disconnects firmware IP from system buffers.
476  *
477  * Input:
478  *	ha = adapter state pointer.
479  *
480  * Returns:
481  *	ql local function return status code.
482  *
483  * Context:
484  *	Kernel context.
485  */
486 int
487 ql_shutdown_ip(ql_adapter_state_t *ha)
488 {
489 	int		rval;
490 	mbx_cmd_t	mc = {0};
491 	mbx_cmd_t	*mcp = &mc;
492 	fc_unsol_buf_t	*ubp;
493 	ql_srb_t	*sp;
494 	uint16_t	index;
495 
496 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
497 
498 	mcp->mb[0] = MBC_UNLOAD_IP;
499 	mcp->out_mb = MBX_0;
500 	mcp->in_mb = MBX_0;
501 	mcp->timeout = MAILBOX_TOV;
502 	rval = ql_mailbox_command(ha, mcp);
503 
504 	ADAPTER_STATE_LOCK(ha);
505 	QL_UB_LOCK(ha);
506 	/* Return all unsolicited buffers that ISP-IP has. */
507 	for (index = 0; index < QL_UB_LIMIT; index++) {
508 		ubp = ha->ub_array[index];
509 		if (ubp != NULL) {
510 			sp = ubp->ub_fca_private;
511 			sp->flags &= ~SRB_UB_IN_ISP;
512 		}
513 	}
514 
515 	ha->ub_outcnt = 0;
516 	QL_UB_UNLOCK(ha);
517 	ha->flags &= ~IP_INITIALIZED;
518 	ADAPTER_STATE_UNLOCK(ha);
519 
520 	if (rval == QL_SUCCESS) {
521 		/* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
522 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
523 	} else {
524 		EL(ha, "failed, rval = %xh\n", rval);
525 	}
526 	return (rval);
527 }
528 
529 /*
530  * ql_online_selftest
531  *	Issue online self test mailbox command.
532  *
533  * Input:
534  *	ha = adapter state pointer.
535  *
536  * Returns:
537  *	ql local function return status code.
538  *
539  * Context:
540  *	Kernel context.
541  */
542 int
543 ql_online_selftest(ql_adapter_state_t *ha)
544 {
545 	int		rval;
546 	mbx_cmd_t	mc = {0};
547 	mbx_cmd_t	*mcp = &mc;
548 
549 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
550 
551 	mcp->mb[0] = MBC_ONLINE_SELF_TEST;
552 	mcp->out_mb = MBX_0;
553 	mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
554 	mcp->timeout = MAILBOX_TOV;
555 	rval = ql_mailbox_command(ha, mcp);
556 
557 	if (rval != QL_SUCCESS) {
558 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
559 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
560 	} else {
561 		/*EMPTY*/
562 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
563 	}
564 	return (rval);
565 }
566 
567 /*
568  * ql_loop_back
569  *	Issue diagnostic loop back frame mailbox command.
570  *
571  * Input:
572  *	ha = adapter state pointer.
573  *	lb = loop back parameter structure pointer.
574  *
575  * Returns:
576  *	ql local function return status code.
577  *
578  * Context:
579  *	Kernel context.
580  */
581 #ifndef apps_64bit
582 int
583 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb, uint32_t h_xmit,
584     uint32_t h_rcv)
585 {
586 	int		rval;
587 	mbx_cmd_t	mc = {0};
588 	mbx_cmd_t	*mcp = &mc;
589 
590 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
591 
592 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
593 	mcp->mb[1] = lb->options;
594 	mcp->mb[6] = LSW(h_rcv);
595 	mcp->mb[7] = MSW(h_rcv);
596 	mcp->mb[10] = LSW(lb->transfer_count);
597 	mcp->mb[11] = MSW(lb->transfer_count);
598 	mcp->mb[12] = lb->transfer_segment_count;
599 	mcp->mb[13] = lb->receive_segment_count;
600 	mcp->mb[14] = LSW(lb->transfer_data_address);
601 	mcp->mb[15] = MSW(lb->transfer_data_address);
602 	mcp->mb[16] = LSW(lb->receive_data_address);
603 	mcp->mb[17] = MSW(lb->receive_data_address);
604 	mcp->mb[18] = LSW(lb->iteration_count);
605 	mcp->mb[19] = MSW(lb->iteration_count);
606 	mcp->mb[20] = LSW(h_xmit);
607 	mcp->mb[21] = MSW(h_xmit);
608 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
609 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
610 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
611 	mcp->timeout = lb->iteration_count / 300;
612 
613 	if (mcp->timeout < MAILBOX_TOV) {
614 		mcp->timeout = MAILBOX_TOV;
615 	}
616 
617 	rval = ql_mailbox_command(ha, mcp);
618 
619 	if (rval != QL_SUCCESS) {
620 		EL(ha, "failed, rval = %xh\n", rval);
621 	} else {
622 		/*EMPTY*/
623 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
624 	}
625 
626 	return (rval);
627 }
628 #else
629 int
630 ql_loop_back(ql_adapter_state_t *ha, lbp_t *lb)
631 {
632 	int		rval;
633 	mbx_cmd_t	mc = {0};
634 	mbx_cmd_t	*mcp = &mc;
635 
636 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
637 
638 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
639 	mcp->mb[1] = lb->options;
640 	mcp->mb[6] = LSW(h_rcv);
641 	mcp->mb[7] = MSW(h_rcv);
642 	mcp->mb[6] = LSW(MSD(lb->receive_data_address));
643 	mcp->mb[7] = MSW(MSD(lb->receive_data_address));
644 	mcp->mb[10] = LSW(lb->transfer_count);
645 	mcp->mb[11] = MSW(lb->transfer_count);
646 	mcp->mb[12] = lb->transfer_segment_count;
647 	mcp->mb[13] = lb->receive_segment_count;
648 	mcp->mb[14] = LSW(lb->transfer_data_address);
649 	mcp->mb[15] = MSW(lb->transfer_data_address);
650 	mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
651 	mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
652 	mcp->mb[16] = LSW(lb->receive_data_address);
653 	mcp->mb[17] = MSW(lb->receive_data_address);
654 	mcp->mb[16] = LSW(LSD(lb->receive_data_address));
655 	mcp->mb[17] = MSW(LSD(lb->receive_data_address));
656 	mcp->mb[18] = LSW(lb->iteration_count);
657 	mcp->mb[19] = MSW(lb->iteration_count);
658 	mcp->mb[20] = LSW(h_xmit);
659 	mcp->mb[21] = MSW(h_xmit);
660 	mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
661 	mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
662 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
663 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
664 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
665 	mcp->timeout = lb->iteration_count / 300;
666 
667 	if (mcp->timeout < MAILBOX_TOV) {
668 		mcp->timeout = MAILBOX_TOV;
669 	}
670 
671 	rval = ql_mailbox_command(ha, mcp);
672 
673 	if (rval != QL_SUCCESS) {
674 		EL(ha, "failed, rval = %xh\n", rval);
675 	} else {
676 		/*EMPTY*/
677 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
678 	}
679 	return (rval);
680 }
681 #endif
682 
683 /*
684  * ql_echo
685  *	Issue an ELS echo using the user specified data to a user specified
686  *	destination
687  *
688  * Input:
689  *	ha:		adapter state pointer.
690  *	echo_pt:	echo parameter structure pointer.
691  *
692  * Returns:
693  *	ql local function return status code.
694  *
695  * Context:
696  *	Kernel context.
697  */
698 int
699 ql_echo(ql_adapter_state_t *ha, echo_t *echo_pt)
700 {
701 	int		rval;
702 	mbx_cmd_t	mc = {0};
703 	mbx_cmd_t	*mcp = &mc;
704 
705 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
706 
707 	mcp->mb[0] = MBC_ECHO;			/* ECHO command */
708 	mcp->mb[1] = echo_pt->options;		/* command options; 64 bit */
709 						/* addressing (bit 6) and */
710 						/* real echo (bit 15 */
711 
712 	/*
713 	 * I know this looks strange, using a field labled "not used"
714 	 * The way the ddi_dma_cookie_t structure/union is defined
715 	 * is a union of one 64 bit entity with an array of two 32
716 	 * bit enititys.  Since we have routines to convert 32 bit
717 	 * entities into 16 bit entities it is easier to use
718 	 * both 32 bit union members then the one 64 bit union
719 	 * member
720 	 */
721 	if (echo_pt->options & BIT_6) {
722 		/* 64 bit addressing */
723 		/* Receive data dest add in system memory bits 47-32 */
724 		mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
725 
726 		/* Receive data dest add in system memory bits 63-48 */
727 		mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
728 
729 		/* Transmit data source address in system memory bits 47-32 */
730 		mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
731 
732 		/* Transmit data source address in system memory bits 63-48 */
733 		mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
734 	} else {
735 		mcp->mb[6] = 0;		/* bits 63-48 */
736 		mcp->mb[7] = 0;		/* bits 47-32 */
737 		mcp->mb[20] = 0;	/* bits 63-48 */
738 		mcp->mb[21] = 0;	/* bits 47-32 */
739 	}
740 
741 	/* transfer count bits 15-0 */
742 	mcp->mb[10] = LSW(echo_pt->transfer_count);
743 
744 	/* Transmit data source address in system memory bits 15-0 */
745 	mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
746 
747 	/*  Transmit data source address in system memory bits 31-16 */
748 	mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
749 
750 	/* Receive data destination address in system memory bits 15-0 */
751 	mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
752 
753 	/*  Receive data destination address in system memory bits 31-16 */
754 	mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
755 
756 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
757 	    MBX_7|MBX_6|MBX_1|MBX_0;
758 	mcp->in_mb = MBX_1|MBX_0;
759 	mcp->timeout = MAILBOX_TOV;
760 
761 	rval = ql_mailbox_command(ha, mcp);
762 
763 	if (rval != QL_SUCCESS) {
764 		EL(ha, "failed, rval = %xh\n", rval);
765 	} else {
766 		/*EMPTY*/
767 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
768 	}
769 	return (rval);
770 }
771 
772 /*
773  * ql_send_change_request
774  *	Issue send change request mailbox command.
775  *
776  * Input:
777  *	ha:	adapter state pointer.
778  *	fmt:	Registration format.
779  *
780  * Returns:
781  *	ql local function return status code.
782  *
783  * Context:
784  *	Kernel context.
785  */
786 int
787 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
788 {
789 	int		rval;
790 	mbx_cmd_t	mc = {0};
791 	mbx_cmd_t	*mcp = &mc;
792 
793 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
794 
795 	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
796 	mcp->mb[1] = fmt;
797 	mcp->out_mb = MBX_1|MBX_0;
798 	if (ha->flags & VP_ENABLED) {
799 		mcp->mb[9] = ha->vp_index;
800 		mcp->out_mb |= MBX_9;
801 	}
802 	mcp->in_mb = MBX_0;
803 	mcp->timeout = MAILBOX_TOV;
804 	rval = ql_mailbox_command(ha, mcp);
805 
806 	if (rval != QL_SUCCESS) {
807 		EL(ha, "failed=%xh\n", rval);
808 	} else {
809 		/*EMPTY*/
810 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
811 	}
812 	return (rval);
813 }
814 
815 /*
816  * ql_send_lfa
817  *	Send a Loop Fabric Address mailbox command.
818  *
819  * Input:
820  *	ha:	adapter state pointer.
821  *	lfa:	LFA command structure pointer.
822  *
823  * Returns:
824  *	ql local function return status code.
825  *
826  * Context:
827  *	Kernel context.
828  */
829 int
830 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
831 {
832 	int		rval;
833 	uint16_t	size;
834 	dma_mem_t	mem_desc;
835 	mbx_cmd_t	mc = {0};
836 	mbx_cmd_t	*mcp = &mc;
837 
838 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
839 
840 	/* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
841 	size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
842 
843 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
844 	if (rval != QL_SUCCESS) {
845 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
846 		return (rval);
847 	}
848 
849 	mcp->mb[0] = MBC_SEND_LFA_COMMAND;
850 	mcp->mb[1] = (uint16_t)(size >> 1);
851 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
852 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
853 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
854 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
855 	mcp->in_mb = MBX_0;
856 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
857 	if (ha->flags & VP_ENABLED) {
858 		mcp->mb[9] = ha->vp_index;
859 		mcp->out_mb |= MBX_9;
860 	}
861 	mcp->timeout = MAILBOX_TOV;
862 	rval = ql_mailbox_command(ha, mcp);
863 
864 	ql_free_dma_resource(ha, &mem_desc);
865 
866 	if (rval != QL_SUCCESS) {
867 		EL(ha, "failed, rval = %xh\n", rval);
868 	} else {
869 		/*EMPTY*/
870 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
871 	}
872 
873 	return (rval);
874 }
875 
876 /*
877  * ql_clear_aca
878  *	Issue clear ACA mailbox command.
879  *
880  * Input:
881  *	ha:	adapter state pointer.
882  *	tq:	target queue pointer.
883  *	lun:	LUN.
884  *
885  * Returns:
886  *	ql local function return status code.
887  *
888  * Context:
889  *	Kernel context.
890  */
891 int
892 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
893 {
894 	int		rval;
895 	mbx_cmd_t	mc = {0};
896 	mbx_cmd_t	*mcp = &mc;
897 
898 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
899 
900 	if (CFG_IST(ha, CFG_CTRL_2425)) {
901 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0);
902 	} else {
903 		mcp->mb[0] = MBC_CLEAR_ACA;
904 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
905 			mcp->mb[1] = tq->loop_id;
906 		} else {
907 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
908 		}
909 		mcp->mb[2] = lun;
910 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
911 		mcp->in_mb = MBX_0;
912 		mcp->timeout = MAILBOX_TOV;
913 		rval = ql_mailbox_command(ha, mcp);
914 	}
915 
916 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
917 
918 	if (rval != QL_SUCCESS) {
919 		EL(ha, "failed, rval = %xh\n", rval);
920 	} else {
921 		/*EMPTY*/
922 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
923 	}
924 
925 	return (rval);
926 }
927 
928 /*
929  * ql_target_reset
930  *	Issue target reset mailbox command.
931  *
932  * Input:
933  *	ha:	adapter state pointer.
934  *	tq:	target queue pointer.
935  *	delay:	seconds.
936  *
937  * Returns:
938  *	ql local function return status code.
939  *
940  * Context:
941  *	Kernel context.
942  */
943 int
944 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
945 {
946 	ql_link_t	*link;
947 	uint16_t	index;
948 	int		rval;
949 	mbx_cmd_t	mc = {0};
950 	mbx_cmd_t	*mcp = &mc;
951 
952 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
953 
954 	if (CFG_IST(ha, CFG_CTRL_2425)) {
955 		/* queue = NULL, all targets. */
956 		if (tq == NULL) {
957 			for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
958 			    index++) {
959 				for (link = ha->dev[index].first; link !=
960 				    NULL; link = link->next) {
961 					tq = link->base_address;
962 					if (!VALID_DEVICE_ID(ha,
963 					    tq->loop_id)) {
964 						continue;
965 					}
966 					rval = ql_task_mgmt_iocb(ha, tq, 0,
967 					    CF_TARGET_RESET, delay);
968 
969 					if (rval != QL_SUCCESS) {
970 						break;
971 					}
972 				}
973 
974 				if (link != NULL) {
975 					break;
976 				}
977 			}
978 			tq = NULL;
979 		} else {
980 			rval = ql_task_mgmt_iocb(ha, tq, 0, CF_TARGET_RESET,
981 			    delay);
982 		}
983 	} else {
984 		/* queue = NULL, all targets. */
985 		if (tq == NULL) {
986 			mcp->mb[0] = MBC_RESET;
987 			mcp->mb[1] = delay;
988 			mcp->out_mb = MBX_1|MBX_0;
989 		} else {
990 			mcp->mb[0] = MBC_TARGET_RESET;
991 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
992 				mcp->mb[1] = tq->loop_id;
993 			} else {
994 				mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
995 			}
996 			mcp->mb[2] = delay;
997 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
998 		}
999 		mcp->in_mb = MBX_0;
1000 		mcp->timeout = MAILBOX_TOV;
1001 		rval = ql_mailbox_command(ha, mcp);
1002 	}
1003 
1004 	tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1005 	    (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1006 
1007 	if (rval != QL_SUCCESS) {
1008 		EL(ha, "failed, rval = %xh\n", rval);
1009 	} else {
1010 		/*EMPTY*/
1011 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1012 	}
1013 
1014 	return (rval);
1015 }
1016 
1017 /*
1018  * ql_abort_target
1019  *	Issue abort target mailbox command.
1020  *
1021  * Input:
1022  *	ha:	adapter state pointer.
1023  *	tq:	target queue pointer.
1024  *	delay:	in seconds.
1025  *
1026  * Returns:
1027  *	qla2x00 local function return status code.
1028  *
1029  * Context:
1030  *	Kernel context.
1031  */
1032 int
1033 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1034 {
1035 	int		rval;
1036 	mbx_cmd_t	mc = {0};
1037 	mbx_cmd_t	*mcp = &mc;
1038 
1039 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1040 
1041 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1042 		rval = ql_task_mgmt_iocb(ha, tq, 0,
1043 		    CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1044 	} else {
1045 		mcp->mb[0] = MBC_ABORT_TARGET;
1046 		/* Don't send Task Mgt */
1047 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1048 			mcp->mb[1] = tq->loop_id;
1049 			mcp->mb[10] = BIT_0;
1050 			mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1051 		} else {
1052 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1053 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1054 		}
1055 		mcp->mb[2] = delay;
1056 		mcp->in_mb = MBX_0;
1057 		mcp->timeout = MAILBOX_TOV;
1058 		rval = ql_mailbox_command(ha, mcp);
1059 	}
1060 
1061 	(void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1062 
1063 	if (rval != QL_SUCCESS) {
1064 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1065 	} else {
1066 		/*EMPTY*/
1067 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1068 	}
1069 	return (rval);
1070 }
1071 
1072 /*
1073  * ql_lun_reset
1074  *	Issue LUN reset task management mailbox command.
1075  *
1076  * Input:
1077  *	ha:	adapter state pointer.
1078  *	tq:	target queue pointer.
1079  *	lun:	LUN.
1080  *
1081  * Returns:
1082  *	ql local function return status code.
1083  *
1084  * Context:
1085  *	Kernel context.
1086  */
1087 int
1088 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1089 {
1090 	int		rval;
1091 	mbx_cmd_t	mc = {0};
1092 	mbx_cmd_t	*mcp = &mc;
1093 
1094 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1095 
1096 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1097 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0);
1098 	} else {
1099 		mcp->mb[0] = MBC_LUN_RESET;
1100 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1101 			mcp->mb[1] = tq->loop_id;
1102 		} else {
1103 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1104 		}
1105 		mcp->mb[2] = lun;
1106 		mcp->mb[3] = 0;
1107 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1108 		mcp->in_mb = MBX_0;
1109 		mcp->timeout = MAILBOX_TOV;
1110 		rval = ql_mailbox_command(ha, mcp);
1111 	}
1112 
1113 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1114 
1115 	if (rval != QL_SUCCESS) {
1116 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1117 	} else {
1118 		/*EMPTY*/
1119 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1120 	}
1121 	return (rval);
1122 }
1123 
1124 /*
1125  * ql_clear_task_set
1126  *	Issue clear task set mailbox command.
1127  *
1128  * Input:
1129  *	ha:	adapter state pointer.
1130  *	tq:	target queue pointer.
1131  *	lun:	LUN.
1132  *
1133  * Returns:
1134  *	ql local function return status code.
1135  *
1136  * Context:
1137  *	Kernel context.
1138  */
1139 int
1140 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1141 {
1142 	int		rval;
1143 	mbx_cmd_t	mc = {0};
1144 	mbx_cmd_t	*mcp = &mc;
1145 
1146 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1147 
1148 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1149 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0);
1150 	} else {
1151 		mcp->mb[0] = MBC_CLEAR_TASK_SET;
1152 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1153 			mcp->mb[1] = tq->loop_id;
1154 		} else {
1155 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1156 		}
1157 		mcp->mb[2] = lun;
1158 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1159 		mcp->in_mb = MBX_0;
1160 		mcp->timeout = MAILBOX_TOV;
1161 		rval = ql_mailbox_command(ha, mcp);
1162 	}
1163 
1164 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1165 
1166 	if (rval != QL_SUCCESS) {
1167 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1168 	} else {
1169 		/*EMPTY*/
1170 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1171 	}
1172 
1173 	return (rval);
1174 }
1175 
1176 /*
1177  * ql_abort_task_set
1178  *	Issue abort task set mailbox command.
1179  *
1180  * Input:
1181  *	ha:	adapter state pointer.
1182  *	tq:	target queue pointer.
1183  *	lun:	LUN.
1184  *
1185  * Returns:
1186  *	ql local function return status code.
1187  *
1188  * Context:
1189  *	Kernel context.
1190  */
1191 int
1192 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1193 {
1194 	int		rval;
1195 	mbx_cmd_t	mc = {0};
1196 	mbx_cmd_t	*mcp = &mc;
1197 
1198 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1199 
1200 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1201 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0);
1202 	} else {
1203 		mcp->mb[0] = MBC_ABORT_TASK_SET;
1204 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1205 			mcp->mb[1] = tq->loop_id;
1206 		} else {
1207 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1208 		}
1209 		mcp->mb[2] = lun;
1210 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1211 		mcp->in_mb = MBX_0;
1212 		mcp->timeout = MAILBOX_TOV;
1213 		rval = ql_mailbox_command(ha, mcp);
1214 	}
1215 
1216 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1217 
1218 	if (rval != QL_SUCCESS) {
1219 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1220 	} else {
1221 		/*EMPTY*/
1222 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1223 	}
1224 
1225 	return (rval);
1226 }
1227 
1228 /*
1229  * ql_task_mgmt_iocb
1230  *	Function issues task management IOCB.
1231  *
1232  * Input:
1233  *	ha:	adapter state pointer.
1234  *	tq:	target queue pointer.
1235  *	lun:	LUN.
1236  *	flags:	control flags.
1237  *	delay:	seconds.
1238  *
1239  * Returns:
1240  *	ql local function return status code.
1241  *
1242  * Context:
1243  *	Kernel context
1244  */
1245 static int
1246 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun,
1247     uint32_t flags, uint16_t delay)
1248 {
1249 	ql_mbx_iocb_t	*pkt;
1250 	int		rval;
1251 	uint32_t	pkt_size;
1252 
1253 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1254 
1255 	pkt_size = sizeof (ql_mbx_iocb_t);
1256 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1257 	if (pkt == NULL) {
1258 		EL(ha, "failed, kmem_zalloc\n");
1259 		return (QL_MEMORY_ALLOC_FAILED);
1260 	}
1261 
1262 	pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1263 	pkt->mgmt.entry_count = 1;
1264 
1265 	pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1266 	pkt->mgmt.delay = (uint16_t)LE_16(delay);
1267 	pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1268 	pkt->mgmt.fcp_lun[2] = LSB(lun);
1269 	pkt->mgmt.fcp_lun[3] = MSB(lun);
1270 	pkt->mgmt.control_flags = LE_32(flags);
1271 	pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1272 	pkt->mgmt.target_id[1] = tq->d_id.b.area;
1273 	pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1274 	pkt->mgmt.vp_index = ha->vp_index;
1275 
1276 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1277 	if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1278 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1279 		    pkt->sts24.entry_status, tq->d_id.b24);
1280 		rval = QL_FUNCTION_PARAMETER_ERROR;
1281 	}
1282 
1283 	LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1284 
1285 	if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1286 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1287 		    pkt->sts24.comp_status, tq->d_id.b24);
1288 		rval = QL_FUNCTION_FAILED;
1289 	}
1290 
1291 	kmem_free(pkt, pkt_size);
1292 
1293 	if (rval != QL_SUCCESS) {
1294 		EL(ha, "failed, rval = %xh\n", rval);
1295 	} else {
1296 		/*EMPTY*/
1297 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1298 	}
1299 
1300 	return (rval);
1301 }
1302 
1303 /*
1304  * ql_loop_port_bypass
1305  *	Issue loop port bypass mailbox command.
1306  *
1307  * Input:
1308  *	ha:	adapter state pointer.
1309  *	tq:	target queue pointer.
1310  *
1311  * Returns:
1312  *	ql local function return status code.
1313  *
1314  * Context:
1315  *	Kernel context.
1316  */
1317 int
1318 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1319 {
1320 	int		rval;
1321 	mbx_cmd_t	mc = {0};
1322 	mbx_cmd_t	*mcp = &mc;
1323 
1324 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1325 
1326 	mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1327 
1328 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1329 		mcp->mb[1] = tq->d_id.b.al_pa;
1330 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1331 		mcp->mb[1] = tq->loop_id;
1332 	} else {
1333 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1334 	}
1335 
1336 	mcp->out_mb = MBX_1|MBX_0;
1337 	mcp->in_mb = MBX_0;
1338 	mcp->timeout = MAILBOX_TOV;
1339 	rval = ql_mailbox_command(ha, mcp);
1340 
1341 	if (rval != QL_SUCCESS) {
1342 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1343 	} else {
1344 		/*EMPTY*/
1345 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1346 	}
1347 
1348 	return (rval);
1349 }
1350 
1351 /*
1352  * ql_loop_port_enable
1353  *	Issue loop port enable mailbox command.
1354  *
1355  * Input:
1356  *	ha:	adapter state pointer.
1357  *	tq:	target queue pointer.
1358  *
1359  * Returns:
1360  *	ql local function return status code.
1361  *
1362  * Context:
1363  *	Kernel context.
1364  */
1365 int
1366 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1367 {
1368 	int		rval;
1369 	mbx_cmd_t	mc = {0};
1370 	mbx_cmd_t	*mcp = &mc;
1371 
1372 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1373 
1374 	mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1375 
1376 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1377 		mcp->mb[1] = tq->d_id.b.al_pa;
1378 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1379 		mcp->mb[1] = tq->loop_id;
1380 	} else {
1381 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1382 	}
1383 	mcp->out_mb = MBX_1|MBX_0;
1384 	mcp->in_mb = MBX_0;
1385 	mcp->timeout = MAILBOX_TOV;
1386 	rval = ql_mailbox_command(ha, mcp);
1387 
1388 	if (rval != QL_SUCCESS) {
1389 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1390 	} else {
1391 		/*EMPTY*/
1392 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1393 	}
1394 
1395 	return (rval);
1396 }
1397 
1398 /*
1399  * ql_login_lport
1400  *	Issue login loop port mailbox command.
1401  *
1402  * Input:
1403  *	ha:		adapter state pointer.
1404  *	tq:		target queue pointer.
1405  *	loop_id:	FC loop id.
1406  *	opt:		options.
1407  *			LLF_NONE, LLF_PLOGI
1408  *
1409  * Returns:
1410  *	ql local function return status code.
1411  *
1412  * Context:
1413  *	Kernel context.
1414  */
1415 int
1416 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1417     uint16_t opt)
1418 {
1419 	int		rval;
1420 	uint16_t	flags;
1421 	ql_mbx_data_t	mr;
1422 	mbx_cmd_t	mc = {0};
1423 	mbx_cmd_t	*mcp = &mc;
1424 
1425 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1426 	    ha->instance, tq->d_id.b24, loop_id);
1427 
1428 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1429 		flags = CF_CMD_PLOGI;
1430 		if ((opt & LLF_PLOGI) == 0) {
1431 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1432 		}
1433 		rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1434 	} else {
1435 		mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1436 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1437 			mcp->mb[1] = loop_id;
1438 		} else {
1439 			mcp->mb[1] = (uint16_t)(loop_id << 8);
1440 		}
1441 		mcp->mb[2] = opt;
1442 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1443 		mcp->in_mb = MBX_0;
1444 		mcp->timeout = MAILBOX_TOV;
1445 		rval = ql_mailbox_command(ha, mcp);
1446 	}
1447 
1448 	if (rval != QL_SUCCESS) {
1449 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1450 		    loop_id, rval);
1451 	} else {
1452 		/*EMPTY*/
1453 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1454 	}
1455 
1456 	return (rval);
1457 }
1458 
1459 /*
1460  * ql_login_fport
1461  *	Issue login fabric port mailbox command.
1462  *
1463  * Input:
1464  *	ha:		adapter state pointer.
1465  *	tq:		target queue pointer.
1466  *	loop_id:	FC loop id.
1467  *	opt:		options.
1468  *			LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1469  *	mr:		pointer for mailbox data.
1470  *
1471  * Returns:
1472  *	ql local function return status code.
1473  *
1474  * Context:
1475  *	Kernel context.
1476  */
1477 int
1478 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1479     uint16_t opt, ql_mbx_data_t *mr)
1480 {
1481 	int		rval;
1482 	uint16_t	flags;
1483 	mbx_cmd_t	mc = {0};
1484 	mbx_cmd_t	*mcp = &mc;
1485 
1486 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1487 	    ha->instance, tq->d_id.b24, loop_id);
1488 
1489 	if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1490 		opt = (uint16_t)(opt | LFF_NO_PRLI);
1491 	}
1492 
1493 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1494 		flags = CF_CMD_PLOGI;
1495 		if (opt & LFF_NO_PLOGI) {
1496 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1497 		}
1498 		if (opt & LFF_NO_PRLI) {
1499 			flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1500 		}
1501 		rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1502 	} else {
1503 		mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1504 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1505 			mcp->mb[1] = loop_id;
1506 			mcp->mb[10] = opt;
1507 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1508 		} else {
1509 			mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1510 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1511 		}
1512 		mcp->mb[2] = MSW(tq->d_id.b24);
1513 		mcp->mb[3] = LSW(tq->d_id.b24);
1514 		mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1515 		mcp->timeout = MAILBOX_TOV;
1516 		rval = ql_mailbox_command(ha, mcp);
1517 
1518 		/* Return mailbox data. */
1519 		if (mr != NULL) {
1520 			mr->mb[0] = mcp->mb[0];
1521 			mr->mb[1] = mcp->mb[1];
1522 			mr->mb[2] = mcp->mb[2];
1523 			mr->mb[6] = mcp->mb[6];
1524 			mr->mb[7] = mcp->mb[7];
1525 		}
1526 	}
1527 
1528 	if (rval != QL_SUCCESS) {
1529 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1530 		    "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1531 		    mr->mb[2]);
1532 	} else {
1533 		/*EMPTY*/
1534 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1535 	}
1536 
1537 	return (rval);
1538 }
1539 
1540 /*
1541  * ql_logout_fabric_port
1542  *	Issue logout fabric port mailbox command.
1543  *
1544  * Input:
1545  *	ha:	adapter state pointer.
1546  *	tq:	target queue pointer.
1547  *
1548  * Returns:
1549  *	ql local function return status code.
1550  *
1551  * Context:
1552  *	Kernel context.
1553  */
1554 int
1555 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1556 {
1557 	int		rval;
1558 	ql_mbx_data_t	mr;
1559 	mbx_cmd_t	mc = {0};
1560 	mbx_cmd_t	*mcp = &mc;
1561 
1562 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1563 
1564 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1565 		rval = ql_log_iocb(ha, tq, tq->loop_id, CFO_IMPLICIT_LOGO |
1566 		    CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE, &mr);
1567 	} else {
1568 		mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1569 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1570 			mcp->mb[1] = tq->loop_id;
1571 			mcp->mb[10] = 0;
1572 			mcp->out_mb = MBX_10|MBX_1|MBX_0;
1573 		} else {
1574 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1575 			mcp->out_mb = MBX_1|MBX_0;
1576 		}
1577 		mcp->in_mb = MBX_0;
1578 		mcp->timeout = MAILBOX_TOV;
1579 		rval = ql_mailbox_command(ha, mcp);
1580 	}
1581 
1582 	if (rval != QL_SUCCESS) {
1583 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1584 		    tq->d_id.b24, tq->loop_id);
1585 	} else {
1586 		/*EMPTY*/
1587 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1588 	}
1589 
1590 	return (rval);
1591 }
1592 
1593 /*
1594  * ql_log_iocb
1595  *	Function issues login/logout IOCB.
1596  *
1597  * Input:
1598  *	ha:		adapter state pointer.
1599  *	tq:		target queue pointer.
1600  *	loop_id:	FC Loop ID.
1601  *	flags:		control flags.
1602  *	mr:		pointer for mailbox data.
1603  *
1604  * Returns:
1605  *	ql local function return status code.
1606  *
1607  * Context:
1608  *	Kernel context.
1609  */
1610 int
1611 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1612     uint16_t flags, ql_mbx_data_t *mr)
1613 {
1614 	ql_mbx_iocb_t	*pkt;
1615 	int		rval;
1616 	uint32_t	pkt_size;
1617 
1618 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1619 
1620 	pkt_size = sizeof (ql_mbx_iocb_t);
1621 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1622 	if (pkt == NULL) {
1623 		EL(ha, "failed, kmem_zalloc\n");
1624 		return (QL_MEMORY_ALLOC_FAILED);
1625 	}
1626 
1627 	pkt->log.entry_type = LOG_TYPE;
1628 	pkt->log.entry_count = 1;
1629 	pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1630 	pkt->log.control_flags = (uint16_t)LE_16(flags);
1631 	pkt->log.port_id[0] = tq->d_id.b.al_pa;
1632 	pkt->log.port_id[1] = tq->d_id.b.area;
1633 	pkt->log.port_id[2] = tq->d_id.b.domain;
1634 	pkt->log.vp_index = ha->vp_index;
1635 
1636 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1637 	if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1638 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1639 		    pkt->log.entry_status, tq->d_id.b24);
1640 		rval = QL_FUNCTION_PARAMETER_ERROR;
1641 	}
1642 
1643 	if (rval == QL_SUCCESS) {
1644 		if (pkt->log.rsp_size == 0xB) {
1645 			LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1646 			tq->cmn_features = MSW(pkt->log.io_param[5]);
1647 			LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1648 			tq->conc_sequences = MSW(pkt->log.io_param[6]);
1649 			tq->relative_offset = LSW(pkt->log.io_param[6]);
1650 			LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1651 			tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1652 			tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1653 			LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1654 			tq->class3_open_sequences_per_exch =
1655 			    MSW(pkt->log.io_param[10]);
1656 			tq->prli_payload_length = 0x14;
1657 		}
1658 		if (mr != NULL) {
1659 			LITTLE_ENDIAN_16(&pkt->log.status);
1660 			LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1661 			LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1662 
1663 			if (pkt->log.status != CS_COMPLETE) {
1664 				EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1665 				    "%xh\n", pkt->log.status,
1666 				    pkt->log.io_param[0],
1667 				    pkt->log.io_param[1]);
1668 
1669 				switch (pkt->log.io_param[0]) {
1670 				case CS0_NO_LINK:
1671 				case CS0_FIRMWARE_NOT_READY:
1672 					mr->mb[0] = MBS_COMMAND_ERROR;
1673 					mr->mb[1] = 1;
1674 					break;
1675 				case CS0_NO_IOCB:
1676 				case CS0_NO_PCB_ALLOCATED:
1677 					mr->mb[0] = MBS_COMMAND_ERROR;
1678 					mr->mb[1] = 2;
1679 					break;
1680 				case CS0_NO_EXCH_CTRL_BLK:
1681 					mr->mb[0] = MBS_COMMAND_ERROR;
1682 					mr->mb[1] = 3;
1683 					break;
1684 				case CS0_COMMAND_FAILED:
1685 					mr->mb[0] = MBS_COMMAND_ERROR;
1686 					mr->mb[1] = 4;
1687 					switch (LSB(pkt->log.io_param[1])) {
1688 					case CS1_PLOGI_RESPONSE_FAILED:
1689 						mr->mb[2] = 3;
1690 						break;
1691 					case CS1_PRLI_FAILED:
1692 						mr->mb[2] = 4;
1693 						break;
1694 					case CS1_PRLI_RESPONSE_FAILED:
1695 						mr->mb[2] = 5;
1696 						break;
1697 					case CS1_COMMAND_LOGGED_OUT:
1698 						mr->mb[2] = 7;
1699 						break;
1700 					case CS1_PLOGI_FAILED:
1701 					default:
1702 						EL(ha, "log iop1 = %xh\n",
1703 						    LSB(pkt->log.io_param[1]))
1704 						mr->mb[2] = 2;
1705 						break;
1706 					}
1707 					break;
1708 				case CS0_PORT_NOT_LOGGED_IN:
1709 					mr->mb[0] = MBS_COMMAND_ERROR;
1710 					mr->mb[1] = 4;
1711 					mr->mb[2] = 7;
1712 					break;
1713 				case CS0_NO_FLOGI_ACC:
1714 				case CS0_NO_FABRIC_PRESENT:
1715 					mr->mb[0] = MBS_COMMAND_ERROR;
1716 					mr->mb[1] = 5;
1717 					break;
1718 				case CS0_ELS_REJECT_RECEIVED:
1719 					mr->mb[0] = MBS_COMMAND_ERROR;
1720 					mr->mb[1] = 0xd;
1721 					break;
1722 				case CS0_PORT_ID_USED:
1723 					mr->mb[0] = MBS_PORT_ID_USED;
1724 					mr->mb[1] = LSW(pkt->log.io_param[1]);
1725 					break;
1726 				case CS0_N_PORT_HANDLE_USED:
1727 					mr->mb[0] = MBS_LOOP_ID_USED;
1728 					mr->mb[1] = MSW(pkt->log.io_param[1]);
1729 					mr->mb[2] = LSW(pkt->log.io_param[1]);
1730 					break;
1731 				case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1732 					mr->mb[0] = MBS_ALL_IDS_IN_USE;
1733 					break;
1734 				case CS0_CMD_PARAMETER_ERROR:
1735 				default:
1736 					EL(ha, "pkt->log iop[0]=%xh\n",
1737 					    pkt->log.io_param[0]);
1738 					mr->mb[0] =
1739 					    MBS_COMMAND_PARAMETER_ERROR;
1740 					break;
1741 				}
1742 			} else {
1743 				QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1744 				    ha->instance, pkt->log.status);
1745 
1746 				mr->mb[0] = MBS_COMMAND_COMPLETE;
1747 				mr->mb[1] = (uint16_t)
1748 				    (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1749 				if (pkt->log.io_param[0] & BIT_8) {
1750 					mr->mb[1] = (uint16_t)
1751 					    (mr->mb[1] | BIT_1);
1752 				}
1753 			}
1754 			rval = mr->mb[0];
1755 		}
1756 
1757 	}
1758 
1759 	kmem_free(pkt, pkt_size);
1760 
1761 	if (rval != QL_SUCCESS) {
1762 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1763 	} else {
1764 		/*EMPTY*/
1765 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1766 	}
1767 
1768 	return (rval);
1769 }
1770 
1771 /*
1772  * ql_get_port_database
1773  *	Issue get port database mailbox command
1774  *	and copy context to device queue.
1775  *
1776  * Input:
1777  *	ha:	adapter state pointer.
1778  *	tq:	target queue pointer.
1779  *	opt:	options.
1780  *		PDF_NONE, PDF_PLOGI, PDF_ADISC
1781  * Returns:
1782  *	ql local function return status code.
1783  *
1784  * Context:
1785  *	Kernel context.
1786  */
1787 int
1788 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1789 {
1790 	int			rval;
1791 	dma_mem_t		mem_desc;
1792 	mbx_cmd_t		mc = {0};
1793 	mbx_cmd_t		*mcp = &mc;
1794 	port_database_23_t	*pd23;
1795 
1796 	ASSERT(!MUTEX_HELD(&ha->mutex));
1797 
1798 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1799 
1800 	pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1801 	if (pd23 == NULL) {
1802 		rval = QL_MEMORY_ALLOC_FAILED;
1803 		EL(ha, "failed, rval = %xh\n", rval);
1804 		return (rval);
1805 	}
1806 
1807 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1808 	    PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1809 		return (QL_MEMORY_ALLOC_FAILED);
1810 	}
1811 
1812 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1813 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1814 		mcp->mb[1] = tq->loop_id;
1815 		mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1816 		mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1817 		mcp->mb[9] = ha->vp_index;
1818 		mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1819 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1820 		    MBX_2|MBX_1|MBX_0;
1821 	} else {
1822 		mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1823 		    MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1824 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1825 			mcp->mb[1] = tq->loop_id;
1826 			mcp->mb[10] = opt;
1827 			mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1828 			    MBX_2|MBX_1|MBX_0;
1829 		} else {
1830 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1831 			mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1832 		}
1833 	}
1834 
1835 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1836 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1837 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1838 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1839 	mcp->in_mb = MBX_0;
1840 	mcp->timeout = MAILBOX_TOV;
1841 	rval = ql_mailbox_command(ha, mcp);
1842 
1843 	if (rval == QL_SUCCESS) {
1844 		ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1845 	}
1846 
1847 	ql_free_dma_resource(ha, &mem_desc);
1848 
1849 	if (rval == QL_SUCCESS) {
1850 		if (CFG_IST(ha, CFG_CTRL_2425)) {
1851 			port_database_24_t *pd24 = (port_database_24_t *)pd23;
1852 
1853 			tq->master_state = pd24->current_login_state;
1854 			tq->slave_state = pd24->last_stable_login_state;
1855 			if (PD_PORT_LOGIN(tq)) {
1856 				/* Names are big endian. */
1857 				bcopy((void *)&pd24->port_name[0],
1858 				    (void *)&tq->port_name[0], 8);
1859 				bcopy((void *)&pd24->node_name[0],
1860 				    (void *)&tq->node_name[0], 8);
1861 				tq->hard_addr.b.al_pa = pd24->hard_address[2];
1862 				tq->hard_addr.b.area = pd24->hard_address[1];
1863 				tq->hard_addr.b.domain = pd24->hard_address[0];
1864 				tq->class3_rcv_data_size =
1865 				    pd24->receive_data_size;
1866 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1867 				tq->prli_svc_param_word_0 =
1868 				    pd24->PRLI_service_parameter_word_0;
1869 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1870 				tq->prli_svc_param_word_3 =
1871 				    pd24->PRLI_service_parameter_word_3;
1872 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1873 			}
1874 		} else {
1875 			tq->master_state = pd23->master_state;
1876 			tq->slave_state = pd23->slave_state;
1877 			if (PD_PORT_LOGIN(tq)) {
1878 				/* Names are big endian. */
1879 				bcopy((void *)&pd23->port_name[0],
1880 				    (void *)&tq->port_name[0], 8);
1881 				bcopy((void *)&pd23->node_name[0],
1882 				    (void *)&tq->node_name[0], 8);
1883 				tq->hard_addr.b.al_pa = pd23->hard_address[2];
1884 				tq->hard_addr.b.area = pd23->hard_address[1];
1885 				tq->hard_addr.b.domain = pd23->hard_address[0];
1886 				tq->cmn_features = pd23->common_features;
1887 				LITTLE_ENDIAN_16(&tq->cmn_features);
1888 				tq->conc_sequences =
1889 				    pd23->total_concurrent_sequences;
1890 				LITTLE_ENDIAN_16(&tq->conc_sequences);
1891 				tq->relative_offset =
1892 				    pd23->RO_by_information_category;
1893 				LITTLE_ENDIAN_16(&tq->relative_offset);
1894 				tq->class3_recipient_ctl = pd23->recipient;
1895 				LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
1896 				tq->class3_rcv_data_size =
1897 				    pd23->receive_data_size;
1898 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1899 				tq->class3_conc_sequences =
1900 				    pd23->concurrent_sequences;
1901 				LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
1902 				tq->class3_open_sequences_per_exch =
1903 				    pd23->open_sequences_per_exchange;
1904 				LITTLE_ENDIAN_16(
1905 				    &tq->class3_open_sequences_per_exch);
1906 				tq->prli_payload_length =
1907 				    pd23->PRLI_payload_length;
1908 				LITTLE_ENDIAN_16(&tq->prli_payload_length);
1909 				tq->prli_svc_param_word_0 =
1910 				    pd23->PRLI_service_parameter_word_0;
1911 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1912 				tq->prli_svc_param_word_3 =
1913 				    pd23->PRLI_service_parameter_word_3;
1914 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1915 			}
1916 		}
1917 
1918 		if (!PD_PORT_LOGIN(tq)) {
1919 			EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
1920 			    "master=%xh, slave=%xh\n", tq->d_id.b24,
1921 			    tq->loop_id, tq->master_state, tq->slave_state);
1922 			rval = QL_NOT_LOGGED_IN;
1923 		} else {
1924 			tq->flags = tq->prli_svc_param_word_3 &
1925 			    PRLI_W3_TARGET_FUNCTION ?
1926 			    tq->flags & ~TQF_INITIATOR_DEVICE :
1927 			    tq->flags | TQF_INITIATOR_DEVICE;
1928 
1929 			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
1930 				tq->flags = tq->prli_svc_param_word_3 &
1931 				    PRLI_W3_RETRY ?
1932 				    tq->flags | TQF_TAPE_DEVICE :
1933 				    tq->flags & ~TQF_TAPE_DEVICE;
1934 			} else {
1935 				tq->flags &= ~TQF_TAPE_DEVICE;
1936 			}
1937 		}
1938 	}
1939 
1940 	kmem_free(pd23, PORT_DATABASE_SIZE);
1941 
1942 	if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
1943 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1944 		    tq->loop_id, rval);
1945 	} else {
1946 		/*EMPTY*/
1947 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1948 	}
1949 
1950 	return (rval);
1951 }
1952 
1953 /*
1954  * ql_get_loop_position_map
1955  *	Issue get loop position map mailbox command.
1956  *
1957  * Input:
1958  *	ha:	adapter state pointer.
1959  *	size:	size of data buffer.
1960  *	bufp:	data pointer for DMA data.
1961  *
1962  * Returns:
1963  *	ql local function return status code.
1964  *
1965  * Context:
1966  *	Kernel context.
1967  */
1968 int
1969 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
1970 {
1971 	int		rval;
1972 	dma_mem_t	mem_desc;
1973 	mbx_cmd_t	mc = {0};
1974 	mbx_cmd_t	*mcp = &mc;
1975 
1976 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1977 
1978 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1979 	    (uint32_t)size)) != QL_SUCCESS) {
1980 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
1981 		return (QL_MEMORY_ALLOC_FAILED);
1982 	}
1983 
1984 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
1985 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1986 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1987 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1988 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1989 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1990 	mcp->in_mb = MBX_1|MBX_0;
1991 	mcp->timeout = MAILBOX_TOV;
1992 	rval = ql_mailbox_command(ha, mcp);
1993 
1994 	if (rval == QL_SUCCESS) {
1995 		ql_get_mbox_dma_data(&mem_desc, bufp);
1996 	}
1997 
1998 	ql_free_dma_resource(ha, &mem_desc);
1999 
2000 	if (rval != QL_SUCCESS) {
2001 		EL(ha, "failed=%xh\n", rval);
2002 	} else {
2003 		/*EMPTY*/
2004 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2005 	}
2006 
2007 	return (rval);
2008 }
2009 
2010 /*
2011  * ql_set_rnid_params
2012  *	Issue set RNID parameters mailbox command.
2013  *
2014  * Input:
2015  *	ha:		adapter state pointer.
2016  *	size:		size of data buffer.
2017  *	bufp:		data pointer for DMA data.
2018  *
2019  * Returns:
2020  *	ql local function return status code.
2021  *
2022  * Context:
2023  *	Kernel context.
2024  */
2025 int
2026 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2027 {
2028 	int		rval;
2029 	dma_mem_t	mem_desc;
2030 	mbx_cmd_t	mc = {0};
2031 	mbx_cmd_t	*mcp = &mc;
2032 
2033 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2034 
2035 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2036 	    (uint32_t)size)) != QL_SUCCESS) {
2037 		EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2038 		return (rval);
2039 	}
2040 
2041 	mcp->mb[0] = MBC_SET_PARAMETERS;
2042 	mcp->mb[1] = 0;
2043 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2044 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2045 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2046 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2047 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2048 	mcp->in_mb = MBX_0;
2049 	mcp->timeout = MAILBOX_TOV;
2050 	rval = ql_mailbox_command(ha, mcp);
2051 
2052 	ql_free_dma_resource(ha, &mem_desc);
2053 
2054 	if (rval != QL_SUCCESS) {
2055 		EL(ha, "failed, rval = %xh\n", rval);
2056 	} else {
2057 		/*EMPTY*/
2058 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2059 	}
2060 
2061 	return (rval);
2062 }
2063 
2064 /*
2065  * ql_send_rnid_els
2066  *	Issue a send node identfication data mailbox command.
2067  *
2068  * Input:
2069  *	ha:		adapter state pointer.
2070  *	loop_id:	FC loop id.
2071  *	opt:		options.
2072  *	size:		size of data buffer.
2073  *	bufp:		data pointer for DMA data.
2074  *
2075  * Returns:
2076  *	ql local function return status code.
2077  *
2078  * Context:
2079  *	Kernel context.
2080  */
2081 int
2082 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2083     size_t size, caddr_t bufp)
2084 {
2085 	int		rval;
2086 	dma_mem_t	mem_desc;
2087 	mbx_cmd_t	mc = {0};
2088 	mbx_cmd_t	*mcp = &mc;
2089 
2090 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2091 
2092 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2093 	    (uint32_t)size)) != QL_SUCCESS) {
2094 		return (QL_MEMORY_ALLOC_FAILED);
2095 	}
2096 
2097 	mcp->mb[0] = MBC_SEND_RNID_ELS;
2098 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2099 		mcp->mb[1] = loop_id;
2100 		mcp->mb[9] = ha->vp_index;
2101 		mcp->mb[10] = opt;
2102 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2103 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2104 		mcp->mb[1] = loop_id;
2105 		mcp->mb[10] = opt;
2106 		mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2107 	} else {
2108 		mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2109 		mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2110 	}
2111 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2112 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2113 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2114 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2115 	mcp->in_mb = MBX_0;
2116 	mcp->timeout = MAILBOX_TOV;
2117 	rval = ql_mailbox_command(ha, mcp);
2118 
2119 	if (rval == QL_SUCCESS) {
2120 		ql_get_mbox_dma_data(&mem_desc, bufp);
2121 	}
2122 
2123 	ql_free_dma_resource(ha, &mem_desc);
2124 
2125 	if (rval != QL_SUCCESS) {
2126 		EL(ha, "failed, rval = %xh\n", rval);
2127 	} else {
2128 		/*EMPTY*/
2129 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2130 	}
2131 
2132 	return (rval);
2133 }
2134 
2135 /*
2136  * ql_get_rnid_params
2137  *	Issue get RNID parameters mailbox command.
2138  *
2139  * Input:
2140  *	ha:	adapter state pointer.
2141  *	size:	size of data buffer.
2142  *	bufp:	data pointer for DMA data.
2143  *
2144  * Returns:
2145  *	ql local function return status code.
2146  *
2147  * Context:
2148  *	Kernel context.
2149  */
2150 int
2151 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2152 {
2153 	int		rval;
2154 	dma_mem_t	mem_desc;
2155 	mbx_cmd_t	mc = {0};
2156 	mbx_cmd_t	*mcp = &mc;
2157 
2158 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2159 
2160 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2161 	    (uint32_t)size)) != QL_SUCCESS) {
2162 		return (QL_MEMORY_ALLOC_FAILED);
2163 	}
2164 
2165 	mcp->mb[0] = MBC_GET_PARAMETERS;
2166 	mcp->mb[1] = 0;
2167 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2168 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2169 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2170 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2171 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2172 	mcp->in_mb = MBX_0;
2173 	mcp->timeout = MAILBOX_TOV;
2174 	rval = ql_mailbox_command(ha, mcp);
2175 
2176 	if (rval == QL_SUCCESS) {
2177 		ql_get_mbox_dma_data(&mem_desc, bufp);
2178 	}
2179 
2180 	ql_free_dma_resource(ha, &mem_desc);
2181 
2182 	if (rval != QL_SUCCESS) {
2183 		EL(ha, "failed=%xh\n", rval);
2184 	} else {
2185 		/*EMPTY*/
2186 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2187 	}
2188 
2189 	return (rval);
2190 }
2191 
2192 /*
2193  * ql_get_link_status
2194  *	Issue get link status mailbox command.
2195  *
2196  * Input:
2197  *	ha:		adapter state pointer.
2198  *	loop_id:	FC loop id or n_port_hdl.
2199  *	size:		size of data buffer.
2200  *	bufp:		data pointer for DMA data.
2201  *	port_no:	port number to query.
2202  *
2203  * Returns:
2204  *	ql local function return status code.
2205  *
2206  * Context:
2207  *	Kernel context.
2208  */
2209 int
2210 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2211     caddr_t bufp, uint8_t port_no)
2212 {
2213 	dma_mem_t	mem_desc;
2214 	mbx_cmd_t	mc = {0};
2215 	mbx_cmd_t	*mcp = &mc;
2216 	int		rval = QL_SUCCESS;
2217 	int		retry = 0;
2218 
2219 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2220 
2221 	do {
2222 		if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2223 		    (uint32_t)size)) != QL_SUCCESS) {
2224 			EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2225 			return (QL_MEMORY_ALLOC_FAILED);
2226 		}
2227 
2228 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2229 		if (CFG_IST(ha, CFG_CTRL_2425)) {
2230 			if (loop_id == ha->loop_id) {
2231 				mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2232 				mcp->mb[8] = (uint16_t)(size >> 2);
2233 				mcp->mb[10] = 0;
2234 				mcp->out_mb = MBX_10|MBX_8;
2235 			} else {
2236 				mcp->mb[1] = loop_id;
2237 				mcp->mb[4] = port_no;
2238 				mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2239 				mcp->out_mb = MBX_10|MBX_4;
2240 			}
2241 		} else {
2242 			if (retry) {
2243 				port_no = (uint8_t)(port_no | BIT_3);
2244 			}
2245 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2246 				mcp->mb[1] = loop_id;
2247 				mcp->mb[10] = port_no;
2248 				mcp->out_mb = MBX_10;
2249 			} else {
2250 				mcp->mb[1] = (uint16_t)((loop_id << 8) |
2251 				    port_no);
2252 				mcp->out_mb = 0;
2253 			}
2254 		}
2255 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2256 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2257 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2258 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2259 		mcp->in_mb = MBX_1|MBX_0;
2260 		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2261 		mcp->timeout = MAILBOX_TOV;
2262 
2263 		rval = ql_mailbox_command(ha, mcp);
2264 
2265 		if (rval == QL_SUCCESS) {
2266 			ql_get_mbox_dma_data(&mem_desc, bufp);
2267 		}
2268 
2269 		ql_free_dma_resource(ha, &mem_desc);
2270 
2271 		if (rval != QL_SUCCESS) {
2272 			EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2273 		}
2274 
2275 		/*
2276 		 * Some of the devices want d_id in the payload,
2277 		 * strictly as per standard. Let's retry.
2278 		 */
2279 
2280 	} while (rval == QL_COMMAND_ERROR && !retry++);
2281 
2282 	if (rval != QL_SUCCESS) {
2283 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2284 	} else {
2285 		/*EMPTY*/
2286 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2287 	}
2288 
2289 	return (rval);
2290 }
2291 
2292 /*
2293  * ql_get_status_counts
2294  *	Issue get adapter link status counts mailbox command.
2295  *
2296  * Input:
2297  *	ha:		adapter state pointer.
2298  *	loop_id:	FC loop id or n_port_hdl.
2299  *	size:		size of data buffer.
2300  *	bufp:		data pointer for DMA data.
2301  *	port_no:	port number to query.
2302  *
2303  * Returns:
2304  *	ql local function return status code.
2305  *
2306  * Context:
2307  *	Kernel context.
2308  */
2309 int
2310 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2311     caddr_t bufp, uint8_t port_no)
2312 {
2313 	dma_mem_t	mem_desc;
2314 	mbx_cmd_t	mc = {0};
2315 	mbx_cmd_t	*mcp = &mc;
2316 	int		rval = QL_SUCCESS;
2317 
2318 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2319 
2320 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2321 	    (uint32_t)size)) != QL_SUCCESS) {
2322 		EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2323 		return (QL_MEMORY_ALLOC_FAILED);
2324 	}
2325 
2326 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2327 		mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2328 		mcp->mb[8] = (uint16_t)(size / 4);
2329 		mcp->mb[10] = 0;
2330 		mcp->out_mb = MBX_10|MBX_8;
2331 	} else {
2332 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2333 
2334 		/* allows reporting when link is down */
2335 		if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2336 			port_no = (uint8_t)(port_no | BIT_6);
2337 		}
2338 
2339 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2340 			mcp->mb[1] = loop_id;
2341 			mcp->mb[10] = port_no;
2342 			mcp->out_mb = MBX_10|MBX_1;
2343 		} else {
2344 			mcp->mb[1] = (uint16_t)((loop_id << 8) |
2345 			    port_no);
2346 			mcp->out_mb = MBX_1;
2347 		}
2348 	}
2349 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2350 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2351 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2352 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2353 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2354 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2355 	mcp->timeout = MAILBOX_TOV;
2356 	rval = ql_mailbox_command(ha, mcp);
2357 
2358 	if (rval == QL_SUCCESS) {
2359 		ql_get_mbox_dma_data(&mem_desc, bufp);
2360 	}
2361 
2362 	ql_free_dma_resource(ha, &mem_desc);
2363 
2364 	if (rval != QL_SUCCESS) {
2365 		EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2366 		    mcp->mb[1], mcp->mb[2]);
2367 	} else {
2368 		/*EMPTY*/
2369 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2370 	}
2371 
2372 	return (rval);
2373 }
2374 
2375 /*
2376  * ql_reset_link_status
2377  *	Issue Reset Link Error Status mailbox command
2378  *
2379  * Input:
2380  *	ha:	adapter state pointer.
2381  *
2382  * Returns:
2383  *	ql local function return status code.
2384  *
2385  * Context:
2386  *	Kernel context.
2387  */
2388 int
2389 ql_reset_link_status(ql_adapter_state_t *ha)
2390 {
2391 	int		rval;
2392 	mbx_cmd_t	mc = {0};
2393 	mbx_cmd_t	*mcp = &mc;
2394 
2395 	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
2396 
2397 	mcp->mb[0] = MBC_RESET_LINK_STATUS;
2398 	mcp->out_mb = MBX_0;
2399 	mcp->in_mb = MBX_0;
2400 	mcp->timeout = MAILBOX_TOV;
2401 	rval = ql_mailbox_command(ha, mcp);
2402 
2403 	if (rval != QL_SUCCESS) {
2404 		EL(ha, "failed=%xh\n", rval);
2405 	} else {
2406 		/*EMPTY*/
2407 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2408 	}
2409 
2410 	return (rval);
2411 }
2412 
2413 /*
2414  * ql_loop_reset
2415  *	Issue loop reset.
2416  *
2417  * Input:
2418  *	ha:	adapter state pointer.
2419  *
2420  * Returns:
2421  *	ql local function return status code.
2422  *
2423  * Context:
2424  *	Kernel context.
2425  */
2426 int
2427 ql_loop_reset(ql_adapter_state_t *ha)
2428 {
2429 	int	rval;
2430 
2431 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2432 
2433 	if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2434 		rval = ql_lip_reset(ha, 0xff);
2435 	} else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2436 		rval = ql_full_login_lip(ha);
2437 	} else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2438 		rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2439 	} else {
2440 		rval = ql_initiate_lip(ha);
2441 	}
2442 
2443 	if (rval != QL_SUCCESS) {
2444 		EL(ha, "failed, rval = %xh\n", rval);
2445 	} else {
2446 		/*EMPTY*/
2447 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2448 	}
2449 
2450 	return (rval);
2451 }
2452 
2453 /*
2454  * ql_initiate_lip
2455  *	Initiate LIP mailbox command.
2456  *
2457  * Input:
2458  *	ha:	adapter state pointer.
2459  *
2460  * Returns:
2461  *	ql local function return status code.
2462  *
2463  * Context:
2464  *	Kernel context.
2465  */
2466 int
2467 ql_initiate_lip(ql_adapter_state_t *ha)
2468 {
2469 	int		rval;
2470 	mbx_cmd_t	mc = {0};
2471 	mbx_cmd_t	*mcp = &mc;
2472 
2473 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2474 
2475 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2476 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2477 		mcp->mb[1] = BIT_4;
2478 		mcp->mb[2] = 0;
2479 		mcp->mb[3] = ha->loop_reset_delay;
2480 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2481 	} else {
2482 		mcp->mb[0] = MBC_INITIATE_LIP;
2483 		mcp->out_mb = MBX_0;
2484 	}
2485 	mcp->in_mb = MBX_0;
2486 	mcp->timeout = MAILBOX_TOV;
2487 	rval = ql_mailbox_command(ha, mcp);
2488 
2489 	if (rval != QL_SUCCESS) {
2490 		EL(ha, "failed, rval = %xh\n", rval);
2491 	} else {
2492 		/*EMPTY*/
2493 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2494 	}
2495 
2496 	return (rval);
2497 }
2498 
2499 /*
2500  * ql_full_login_lip
2501  *	Issue full login LIP mailbox command.
2502  *
2503  * Input:
2504  *	ha:	adapter state pointer.
2505  *
2506  * Returns:
2507  *	ql local function return status code.
2508  *
2509  * Context:
2510  *	Kernel context.
2511  */
2512 int
2513 ql_full_login_lip(ql_adapter_state_t *ha)
2514 {
2515 	int		rval;
2516 	mbx_cmd_t	mc = {0};
2517 	mbx_cmd_t	*mcp = &mc;
2518 
2519 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2520 
2521 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2522 	mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ? BIT_3 : 0);
2523 	mcp->mb[2] = 0;
2524 	mcp->mb[3] = 0;
2525 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2526 	mcp->in_mb = MBX_0;
2527 	mcp->timeout = MAILBOX_TOV;
2528 	rval = ql_mailbox_command(ha, mcp);
2529 
2530 	if (rval != QL_SUCCESS) {
2531 		EL(ha, "failed, rval = %xh\n", rval);
2532 	} else {
2533 		/*EMPTY*/
2534 		QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2535 	}
2536 
2537 	return (rval);
2538 }
2539 
2540 /*
2541  * ql_lip_reset
2542  *	Issue lip reset to a port.
2543  *
2544  * Input:
2545  *	ha:		adapter state pointer.
2546  *	loop_id:	FC loop id.
2547  *
2548  * Returns:
2549  *	ql local function return status code.
2550  *
2551  * Context:
2552  *	Kernel context.
2553  */
2554 int
2555 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2556 {
2557 	int		rval;
2558 	mbx_cmd_t	mc = {0};
2559 	mbx_cmd_t	*mcp = &mc;
2560 
2561 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2562 
2563 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2564 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2565 		mcp->mb[1] = BIT_6;
2566 		mcp->mb[2] = 0;
2567 		mcp->mb[3] = ha->loop_reset_delay;
2568 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2569 	} else {
2570 		mcp->mb[0] = MBC_LIP_RESET;
2571 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2572 			mcp->mb[1] = loop_id;
2573 			mcp->mb[10] = 0;
2574 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2575 		} else {
2576 			mcp->mb[1] = (uint16_t)(loop_id << 8);
2577 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2578 		}
2579 		mcp->mb[2] = ha->loop_reset_delay;
2580 		mcp->mb[3] = 0;
2581 	}
2582 	mcp->in_mb = MBX_0;
2583 	mcp->timeout = MAILBOX_TOV;
2584 	rval = ql_mailbox_command(ha, mcp);
2585 
2586 	if (rval != QL_SUCCESS) {
2587 		EL(ha, "failed, rval = %xh\n", rval);
2588 	} else {
2589 		/*EMPTY*/
2590 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2591 	}
2592 
2593 	return (rval);
2594 }
2595 
2596 /*
2597  * ql_abort_command
2598  *	Abort command aborts a specified IOCB.
2599  *
2600  * Input:
2601  *	ha:	adapter state pointer.
2602  *	sp:	SRB structure pointer.
2603  *
2604  * Returns:
2605  *	ql local function return status code.
2606  *
2607  * Context:
2608  *	Kernel context.
2609  */
2610 int
2611 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2612 {
2613 	int		rval;
2614 	mbx_cmd_t	mc = {0};
2615 	mbx_cmd_t	*mcp = &mc;
2616 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2617 
2618 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2619 
2620 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2621 		rval = ql_abort_cmd_iocb(ha, sp);
2622 	} else {
2623 		mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2624 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2625 			mcp->mb[1] = tq->loop_id;
2626 		} else {
2627 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2628 		}
2629 		mcp->mb[2] = LSW(sp->handle);
2630 		mcp->mb[3] = MSW(sp->handle);
2631 		mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2632 		    sp->lun_queue->lun_no : 0);
2633 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2634 		mcp->in_mb = MBX_0;
2635 		mcp->timeout = MAILBOX_TOV;
2636 		rval = ql_mailbox_command(ha, mcp);
2637 	}
2638 
2639 	if (rval != QL_SUCCESS) {
2640 		EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2641 		    tq->d_id.b24, sp->handle);
2642 	} else {
2643 		/*EMPTY*/
2644 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2645 	}
2646 
2647 	return (rval);
2648 }
2649 
2650 /*
2651  * ql_abort_cmd_iocb
2652  *	Function issues abort command IOCB.
2653  *
2654  * Input:
2655  *	ha:	adapter state pointer.
2656  *	sp:	SRB structure pointer.
2657  *
2658  * Returns:
2659  *	ql local function return status code.
2660  *
2661  * Context:
2662  *	Interrupt or Kernel context, no mailbox commands allowed.
2663  */
2664 static int
2665 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2666 {
2667 	ql_mbx_iocb_t	*pkt;
2668 	int		rval;
2669 	uint32_t	pkt_size;
2670 	uint16_t	comp_status;
2671 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2672 
2673 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2674 
2675 	pkt_size = sizeof (ql_mbx_iocb_t);
2676 	if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2677 		EL(ha, "failed, kmem_zalloc\n");
2678 		return (QL_MEMORY_ALLOC_FAILED);
2679 	}
2680 
2681 	pkt->abo.entry_type = ABORT_CMD_TYPE;
2682 	pkt->abo.entry_count = 1;
2683 	pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2684 	pkt->abo.options = AF_NO_ABTS;
2685 	pkt->abo.cmd_handle = LE_32(sp->handle);
2686 	pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2687 	pkt->abo.target_id[1] = tq->d_id.b.area;
2688 	pkt->abo.target_id[2] = tq->d_id.b.domain;
2689 	pkt->abo.vp_index = ha->vp_index;
2690 
2691 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2692 
2693 	if (rval == QL_SUCCESS && (pkt->abo.entry_status  & 0x3c) != 0) {
2694 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2695 		    pkt->abo.entry_status, tq->d_id.b24);
2696 		rval = QL_FUNCTION_PARAMETER_ERROR;
2697 	}
2698 
2699 	comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2700 	if (rval == QL_SUCCESS && comp_status != CS_COMPLETE) {
2701 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2702 		    comp_status, tq->d_id.b24);
2703 		rval = QL_FUNCTION_FAILED;
2704 	}
2705 
2706 	kmem_free(pkt, pkt_size);
2707 
2708 	if (rval != QL_SUCCESS) {
2709 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2710 	} else {
2711 		/*EMPTY*/
2712 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2713 	}
2714 
2715 	return (rval);
2716 }
2717 
2718 /*
2719  * ql_verify_checksum
2720  *	Verify loaded RISC firmware.
2721  *
2722  * Input:
2723  *	ha = adapter state pointer.
2724  *
2725  * Returns:
2726  *	ql local function return status code.
2727  *
2728  * Context:
2729  *	Kernel context.
2730  */
2731 int
2732 ql_verify_checksum(ql_adapter_state_t *ha)
2733 {
2734 	int		rval;
2735 	mbx_cmd_t	mc = {0};
2736 	mbx_cmd_t	*mcp = &mc;
2737 
2738 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2739 
2740 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2741 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2742 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2743 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2744 	} else {
2745 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2746 	}
2747 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2748 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2749 	mcp->timeout = MAILBOX_TOV;
2750 	rval = ql_mailbox_command(ha, mcp);
2751 
2752 	if (rval != QL_SUCCESS) {
2753 		EL(ha, "failed, rval = %xh\n", rval);
2754 	} else {
2755 		/*EMPTY*/
2756 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2757 	}
2758 
2759 	return (rval);
2760 }
2761 
2762 /*
2763  * ql_get_id_list
2764  *	Get d_id and loop ID list.
2765  *
2766  * Input:
2767  *	ha:	adapter state pointer.
2768  *	bp:	data pointer for DMA data.
2769  *	size:	size of data buffer.
2770  *	mr:	pointer for mailbox data.
2771  *
2772  * Returns:
2773  *	ql local function return status code.
2774  *
2775  * Context:
2776  *	Kernel context.
2777  */
2778 int
2779 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2780     ql_mbx_data_t *mr)
2781 {
2782 	int		rval;
2783 	dma_mem_t	mem_desc;
2784 	mbx_cmd_t	mc = {0};
2785 	mbx_cmd_t	*mcp = &mc;
2786 
2787 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2788 
2789 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2790 	    (uint32_t)size)) != QL_SUCCESS) {
2791 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2792 		return (QL_MEMORY_ALLOC_FAILED);
2793 	}
2794 
2795 	mcp->mb[0] = MBC_GET_ID_LIST;
2796 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2797 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2798 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2799 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2800 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2801 		mcp->mb[8] = (uint16_t)size;
2802 		mcp->mb[9] = ha->vp_index;
2803 		mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2804 	} else {
2805 		mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2806 		mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2807 		mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2808 		mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2809 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2810 	}
2811 	mcp->in_mb = MBX_1|MBX_0;
2812 	mcp->timeout = MAILBOX_TOV;
2813 	rval = ql_mailbox_command(ha, mcp);
2814 
2815 	if (rval == QL_SUCCESS) {
2816 		ql_get_mbox_dma_data(&mem_desc, bp);
2817 	}
2818 
2819 	ql_free_dma_resource(ha, &mem_desc);
2820 
2821 	/* Return mailbox data. */
2822 	if (mr != NULL) {
2823 		mr->mb[0] = mcp->mb[0];
2824 		mr->mb[1] = mcp->mb[1];
2825 	}
2826 
2827 	if (rval != QL_SUCCESS) {
2828 		EL(ha, "failed, rval = %xh\n", rval);
2829 	} else {
2830 		/*EMPTY*/
2831 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2832 	}
2833 
2834 	return (rval);
2835 }
2836 
2837 /*
2838  * ql_wrt_risc_ram
2839  *	Load RISC RAM.
2840  *
2841  * Input:
2842  *	ha:		adapter state pointer.
2843  *	risc_address:	risc ram word address.
2844  *	bp:		DMA pointer.
2845  *	word_count:	16/32bit word count.
2846  *
2847  * Returns:
2848  *	ql local function return status code.
2849  *
2850  * Context:
2851  *	Kernel context.
2852  */
2853 int
2854 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2855     uint32_t word_count)
2856 {
2857 	int		rval;
2858 	mbx_cmd_t	mc = {0};
2859 	mbx_cmd_t	*mcp = &mc;
2860 
2861 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2862 
2863 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2864 		mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2865 		mcp->mb[4] = MSW(word_count);
2866 		mcp->mb[5] = LSW(word_count);
2867 		mcp->mb[6] = MSW(MSD(bp));
2868 		mcp->mb[7] = LSW(MSD(bp));
2869 		mcp->mb[8] = MSW(risc_address);
2870 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2871 		    MBX_0;
2872 	} else {
2873 		mcp->mb[0] = MBC_LOAD_RAM;
2874 		mcp->mb[4] = LSW(word_count);
2875 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2876 	}
2877 	mcp->mb[1] = LSW(risc_address);
2878 	mcp->mb[2] = MSW(LSD(bp));
2879 	mcp->mb[3] = LSW(LSD(bp));
2880 	mcp->in_mb = MBX_0;
2881 	mcp->timeout = MAILBOX_TOV;
2882 
2883 	rval = ql_mailbox_command(ha, mcp);
2884 
2885 	if (rval != QL_SUCCESS) {
2886 		EL(ha, "failed, rval = %xh\n", rval);
2887 	} else {
2888 		/*EMPTY*/
2889 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2890 	}
2891 
2892 	return (rval);
2893 }
2894 
2895 /*
2896  * ql_rd_risc_ram
2897  *	Get RISC RAM.
2898  *
2899  * Input:
2900  *	ha:		adapter state pointer.
2901  *	risc_address:	risc ram word address.
2902  *	bp:		direct data pointer.
2903  *	word_count:	16/32bit word count.
2904  *
2905  * Returns:
2906  *	ql local function return status code.
2907  *
2908  * Context:
2909  *	Kernel context.
2910  */
2911 int
2912 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2913     uint32_t word_count)
2914 {
2915 	int		rval;
2916 	mbx_cmd_t	mc = {0};
2917 	mbx_cmd_t	*mcp = &mc;
2918 
2919 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2920 
2921 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2922 		mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
2923 		mcp->mb[1] = LSW(risc_address);
2924 		mcp->mb[2] = MSW(LSD(bp));
2925 		mcp->mb[3] = LSW(LSD(bp));
2926 		mcp->mb[4] = MSW(word_count);
2927 		mcp->mb[5] = LSW(word_count);
2928 		mcp->mb[6] = MSW(MSD(bp));
2929 		mcp->mb[7] = LSW(MSD(bp));
2930 		mcp->mb[8] = MSW(risc_address);
2931 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2932 		    MBX_0;
2933 	} else {
2934 		mcp->mb[0] = MBC_DUMP_RAM;	/* doesn't support 64bit addr */
2935 		mcp->mb[1] = LSW(risc_address);
2936 		mcp->mb[2] = MSW(LSD(bp));
2937 		mcp->mb[3] = LSW(LSD(bp));
2938 		mcp->mb[4] = LSW(word_count);
2939 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2940 	}
2941 	mcp->in_mb = MBX_0;
2942 	mcp->timeout = MAILBOX_TOV;
2943 	rval = ql_mailbox_command(ha, mcp);
2944 
2945 	if (rval != QL_SUCCESS) {
2946 		EL(ha, "failed, rval = %xh\n", rval);
2947 	} else {
2948 		/*EMPTY*/
2949 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2950 	}
2951 
2952 	return (rval);
2953 }
2954 
2955 /*
2956  * ql_issue_mbx_iocb
2957  *	Issue IOCB using mailbox command
2958  *
2959  * Input:
2960  *	ha:	adapter state pointer.
2961  *	bp:	buffer pointer.
2962  *	size:	buffer size.
2963  *
2964  * Returns:
2965  *	ql local function return status code.
2966  *
2967  * Context:
2968  *	Kernel context.
2969  */
2970 int
2971 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
2972 {
2973 	int		rval;
2974 	dma_mem_t	mem_desc;
2975 	mbx_cmd_t	mc = {0};
2976 	mbx_cmd_t	*mcp = &mc;
2977 
2978 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2979 
2980 
2981 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
2982 	    QL_SUCCESS) {
2983 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
2984 		return (rval);
2985 	}
2986 
2987 	mcp->mb[0] = MBC_EXECUTE_IOCB;
2988 	mcp->mb[1] = 0;
2989 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2990 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2991 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2992 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2993 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2994 	mcp->in_mb = MBX_1|MBX_0;
2995 	mcp->timeout = MAILBOX_TOV + 5;
2996 	rval = ql_mailbox_command(ha, mcp);
2997 
2998 	if (rval == QL_SUCCESS) {
2999 		ql_get_mbox_dma_data(&mem_desc, bp);
3000 	}
3001 
3002 	ql_free_dma_resource(ha, &mem_desc);
3003 
3004 	if (rval != QL_SUCCESS) {
3005 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3006 	} else {
3007 		/*EMPTY*/
3008 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3009 	}
3010 
3011 	return (rval);
3012 }
3013 
3014 /*
3015  * ql_mbx_wrap_test
3016  *	Mailbox register wrap test.
3017  *
3018  * Input:
3019  *	ha:	adapter state pointer.
3020  *	mr:	pointer for in/out mailbox data.
3021  *
3022  * Returns:
3023  *	ql local function return status code.
3024  *
3025  * Context:
3026  *	Kernel context.
3027  */
3028 int
3029 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3030 {
3031 	int		rval;
3032 	mbx_cmd_t	mc = {0};
3033 	mbx_cmd_t	*mcp = &mc;
3034 
3035 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3036 
3037 	if (mr != NULL) {
3038 		mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3039 		mcp->mb[1] = mr->mb[1];
3040 		mcp->mb[2] = mr->mb[2];
3041 		mcp->mb[3] = mr->mb[3];
3042 		mcp->mb[4] = mr->mb[4];
3043 		mcp->mb[5] = mr->mb[5];
3044 		mcp->mb[6] = mr->mb[6];
3045 		mcp->mb[7] = mr->mb[7];
3046 		mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3047 		mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3048 		mcp->timeout = MAILBOX_TOV;
3049 		rval = ql_mailbox_command(ha, mcp);
3050 		if (rval == QL_SUCCESS) {
3051 			mr->mb[1] = mcp->mb[1];
3052 			mr->mb[2] = mcp->mb[2];
3053 			mr->mb[3] = mcp->mb[3];
3054 			mr->mb[4] = mcp->mb[4];
3055 			mr->mb[5] = mcp->mb[5];
3056 			mr->mb[6] = mcp->mb[6];
3057 			mr->mb[7] = mcp->mb[7];
3058 		}
3059 	} else {
3060 		rval = QL_FUNCTION_PARAMETER_ERROR;
3061 	}
3062 
3063 	if (rval != QL_SUCCESS) {
3064 		EL(ha, "failed=%xh\n", rval);
3065 	} else {
3066 		/*EMPTY*/
3067 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3068 	}
3069 
3070 	return (rval);
3071 }
3072 
3073 /*
3074  * ql_execute_fw
3075  *	Start adapter firmware.
3076  *
3077  * Input:
3078  *	ha:	adapter state pointer.
3079  *
3080  * Returns:
3081  *	qla2x00 local function return status code.
3082  *
3083  * Context:
3084  *	Kernel context.
3085  */
3086 int
3087 ql_execute_fw(ql_adapter_state_t *ha)
3088 {
3089 	int		rval;
3090 	mbx_cmd_t	mc = {0};
3091 	mbx_cmd_t	*mcp = &mc;
3092 
3093 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3094 
3095 	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3096 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3097 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3098 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3099 	} else {
3100 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3101 		mcp->mb[2] = 0;
3102 	}
3103 	mcp->mb[3] = 0;
3104 	mcp->mb[4] = 0;
3105 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3106 	mcp->in_mb = MBX_0;
3107 	mcp->timeout = MAILBOX_TOV;
3108 	rval = ql_mailbox_command(ha, mcp);
3109 
3110 	if (CFG_IST(ha, CFG_CTRL_2200)) {
3111 		rval = QL_SUCCESS;
3112 	}
3113 
3114 	if (rval != QL_SUCCESS) {
3115 		EL(ha, "failed=%xh\n", rval);
3116 	} else {
3117 		/*EMPTY*/
3118 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3119 	}
3120 
3121 	return (rval);
3122 }
3123 
3124 /*
3125  * ql_get_firmware_option
3126  *	 Get Firmware Options Mailbox Command.
3127  *
3128  * Input:
3129  *	ha:	adapter state pointer.
3130  *	mr:	pointer for mailbox data.
3131  *
3132  * Returns:
3133  *	ql local function return status code.
3134  *
3135  * Context:
3136  *	Kernel context.
3137  */
3138 int
3139 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3140 {
3141 	int		rval;
3142 	mbx_cmd_t	mc = {0};
3143 	mbx_cmd_t	*mcp = &mc;
3144 
3145 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3146 
3147 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3148 	mcp->out_mb = MBX_0;
3149 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3150 	mcp->timeout = MAILBOX_TOV;
3151 	rval = ql_mailbox_command(ha, mcp);
3152 
3153 	/* Return mailbox data. */
3154 	if (mr != NULL) {
3155 		mr->mb[0] = mcp->mb[0];
3156 		mr->mb[1] = mcp->mb[1];
3157 		mr->mb[2] = mcp->mb[2];
3158 		mr->mb[3] = mcp->mb[3];
3159 	}
3160 
3161 	if (rval != QL_SUCCESS) {
3162 		EL(ha, "failed=%xh\n", rval);
3163 	} else {
3164 		/*EMPTY*/
3165 		QL_PRINT_9(CE_CONT, "(%d): done\n", ha->instance);
3166 	}
3167 
3168 	return (rval);
3169 }
3170 
3171 /*
3172  * ql_set_firmware_option
3173  *	 Set Firmware Options Mailbox Command.
3174  *
3175  * Input:
3176  *	ha:	adapter state pointer.
3177  *	mr:	pointer for mailbox data.
3178  *
3179  * Returns:
3180  *	ql local function return status code.
3181  *
3182  * Context:
3183  *	Kernel context.
3184  */
3185 int
3186 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3187 {
3188 	int		rval;
3189 	mbx_cmd_t	mc = {0};
3190 	mbx_cmd_t	*mcp = &mc;
3191 
3192 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3193 
3194 	if (mr != NULL) {
3195 		mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3196 		mcp->mb[1] = mr->mb[1];
3197 		mcp->mb[2] = mr->mb[2];
3198 		mcp->mb[3] = mr->mb[3];
3199 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3200 		mcp->in_mb = MBX_0;
3201 		mcp->timeout = MAILBOX_TOV;
3202 		rval = ql_mailbox_command(ha, mcp);
3203 	} else {
3204 		rval = QL_FUNCTION_PARAMETER_ERROR;
3205 	}
3206 
3207 	if (rval != QL_SUCCESS) {
3208 		EL(ha, "failed=%xh\n", rval);
3209 	} else {
3210 		/*EMPTY*/
3211 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3212 	}
3213 
3214 	return (rval);
3215 }
3216 
3217 /*
3218  * ql_init_firmware
3219  *	 Initialize firmware mailbox command.
3220  *
3221  * Input:
3222  *	ha:	adapter state pointer.
3223  *	ha->init_ctrl_blk = setup for transmit.
3224  *
3225  * Returns:
3226  *	ql local function return status code.
3227  *
3228  * Context:
3229  *	Kernel context.
3230  */
3231 int
3232 ql_init_firmware(ql_adapter_state_t *ha)
3233 {
3234 	int		rval;
3235 	dma_mem_t	mem_desc;
3236 	mbx_cmd_t	mc = {0};
3237 	mbx_cmd_t	*mcp = &mc;
3238 
3239 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3240 
3241 	if (CFG_IST(ha, CFG_CTRL_2425)) {
3242 		WRT32_IO_REG(ha, req_in, 0);
3243 		WRT32_IO_REG(ha, resp_out, 0);
3244 		WRT32_IO_REG(ha, pri_req_in, 0);
3245 		WRT32_IO_REG(ha, atio_req_out, 0);
3246 	} else {
3247 		WRT16_IO_REG(ha, req_in, 0);
3248 		WRT16_IO_REG(ha, resp_out, 0);
3249 	}
3250 
3251 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3252 	    (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3253 	    QL_SUCCESS) {
3254 		EL(ha, "dma setup failed=%xh\n", rval);
3255 		return (rval);
3256 	}
3257 
3258 	mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3259 	    MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3260 
3261 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
3262 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2200) ?
3263 		    0x204c : 0x52);
3264 	} else {
3265 		mcp->mb[1] = 0;
3266 	}
3267 
3268 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3269 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3270 	mcp->mb[4] = 0;
3271 	mcp->mb[5] = 0;
3272 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3273 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3274 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3275 	mcp->in_mb = MBX_0|MBX_2;
3276 	mcp->timeout = MAILBOX_TOV;
3277 	rval = ql_mailbox_command(ha, mcp);
3278 
3279 	if (rval == QL_SUCCESS) {
3280 		ha->sfp_stat = mcp->mb[2];
3281 	}
3282 	ql_free_dma_resource(ha, &mem_desc);
3283 
3284 	if (rval != QL_SUCCESS) {
3285 		EL(ha, "failed=%xh\n", rval);
3286 	} else {
3287 		/*EMPTY*/
3288 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3289 	}
3290 
3291 	return (rval);
3292 }
3293 
3294 /*
3295  * ql_get_firmware_state
3296  *	Get adapter firmware state.
3297  *
3298  * Input:
3299  *	ha:	adapter state pointer.
3300  *	mr:	pointer for mailbox data.
3301  *
3302  * Returns:
3303  *	ql local function return status code.
3304  *
3305  * Context:
3306  *	Kernel context.
3307  */
3308 int
3309 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3310 {
3311 	int		rval;
3312 	mbx_cmd_t	mc = {0};
3313 	mbx_cmd_t	*mcp = &mc;
3314 
3315 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3316 
3317 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3318 	mcp->out_mb = MBX_0;
3319 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3320 	mcp->timeout = MAILBOX_TOV;
3321 	rval = ql_mailbox_command(ha, mcp);
3322 
3323 	/* Return mailbox data. */
3324 	if (mr != NULL) {
3325 		mr->mb[1] = mcp->mb[1];
3326 		mr->mb[2] = mcp->mb[2];
3327 		mr->mb[3] = mcp->mb[3];
3328 	}
3329 
3330 	ha->sfp_stat = mcp->mb[2];
3331 
3332 	if (rval != QL_SUCCESS) {
3333 		EL(ha, "failed=%xh\n", rval);
3334 	} else {
3335 		/*EMPTY*/
3336 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3337 	}
3338 
3339 	return (rval);
3340 }
3341 
3342 /*
3343  * ql_get_adapter_id
3344  *	Get adapter ID and topology.
3345  *
3346  * Input:
3347  *	ha:	adapter state pointer.
3348  *	mr:	pointer for mailbox data.
3349  *
3350  * Returns:
3351  *	ql local function return status code.
3352  *
3353  * Context:
3354  *	Kernel context.
3355  */
3356 int
3357 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3358 {
3359 	int		rval;
3360 	mbx_cmd_t	mc = {0};
3361 	mbx_cmd_t	*mcp = &mc;
3362 
3363 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3364 
3365 	mcp->mb[0] = MBC_GET_ID;
3366 	mcp->out_mb = MBX_0;
3367 	if (ha->flags & VP_ENABLED) {
3368 		mcp->mb[9] = ha->vp_index;
3369 		mcp->out_mb |= MBX_9;
3370 	} else {
3371 		mcp->mb[9] = 0;
3372 		mcp->out_mb |= MBX_9;
3373 	}
3374 
3375 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3376 	mcp->timeout = MAILBOX_TOV;
3377 
3378 	rval = ql_mailbox_command(ha, mcp);
3379 
3380 	/* Return mailbox data. */
3381 	if (mr != NULL) {
3382 		mr->mb[1] = mcp->mb[1];
3383 		mr->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_2425) ?
3384 		    0xffff : mcp->mb[1]);
3385 		mr->mb[2] = mcp->mb[2];
3386 		mr->mb[3] = mcp->mb[3];
3387 		mr->mb[6] = mcp->mb[6];
3388 		mr->mb[7] = mcp->mb[7];
3389 	}
3390 
3391 	if (rval != QL_SUCCESS) {
3392 		EL(ha, "failed=%xh\n", rval);
3393 	} else {
3394 		/*EMPTY*/
3395 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3396 	}
3397 
3398 	return (rval);
3399 }
3400 
3401 /*
3402  * ql_get_fw_version
3403  *	Get firmware version.
3404  *
3405  * Input:
3406  *	ha:	adapter state pointer.
3407  *	mr:	pointer for mailbox data.
3408  *
3409  * Returns:
3410  *	ql local function return status code.
3411  *
3412  * Context:
3413  *	Kernel context.
3414  */
3415 int
3416 ql_get_fw_version(ql_adapter_state_t *ha,  ql_mbx_data_t *mr)
3417 {
3418 	int		rval;
3419 	mbx_cmd_t	mc = {0};
3420 	mbx_cmd_t	*mcp = &mc;
3421 
3422 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3423 
3424 	mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3425 	mcp->out_mb = MBX_0;
3426 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3427 	mcp->timeout = MAILBOX_TOV;
3428 	rval = ql_mailbox_command(ha, mcp);
3429 
3430 	/* Return mailbox data. */
3431 	if (mr != NULL) {
3432 		mr->mb[1] = mcp->mb[1];
3433 		mr->mb[2] = mcp->mb[2];
3434 		mr->mb[3] = mcp->mb[3];
3435 		mr->mb[4] = mcp->mb[4];
3436 		mr->mb[5] = mcp->mb[5];
3437 		mr->mb[6] = mcp->mb[6];
3438 	}
3439 
3440 	if (rval != QL_SUCCESS) {
3441 		EL(ha, "failed=%xh\n", rval);
3442 	} else {
3443 		/*EMPTY*/
3444 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3445 	}
3446 
3447 	return (rval);
3448 }
3449 
3450 /*
3451  * ql_data_rate
3452  *	 Issue data rate Mailbox Command.
3453  *
3454  * Input:
3455  *	ha:	adapter state pointer.
3456  *	mr:	pointer for mailbox data.
3457  *
3458  * Returns:
3459  *	ql local function return status code.
3460  *
3461  * Context:
3462  *	Kernel context.
3463  */
3464 int
3465 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3466 {
3467 	int		rval;
3468 	mbx_cmd_t	mc = {0};
3469 	mbx_cmd_t	*mcp = &mc;
3470 
3471 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3472 
3473 	if (mr != NULL) {
3474 		mcp->mb[0] = MBC_DATA_RATE;
3475 		mcp->mb[1] = mr->mb[1];
3476 		mcp->mb[2] = mr->mb[2];
3477 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
3478 		mcp->in_mb = MBX_2|MBX_1|MBX_0;
3479 		mcp->timeout = MAILBOX_TOV;
3480 		rval = ql_mailbox_command(ha, mcp);
3481 
3482 		/* Return mailbox data. */
3483 		mr->mb[1] = mcp->mb[1];
3484 		mr->mb[2] = mcp->mb[2];
3485 	} else {
3486 		rval = QL_FUNCTION_PARAMETER_ERROR;
3487 	}
3488 
3489 	ha->sfp_stat = mcp->mb[2];
3490 
3491 	if (rval != QL_SUCCESS) {
3492 		EL(ha, "failed=%xh\n", rval);
3493 	} else {
3494 		/*EMPTY*/
3495 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3496 	}
3497 
3498 	return (rval);
3499 }
3500 
3501 /*
3502  * ql_Diag_Loopback
3503  *	Issue Reset Link Status mailbox command
3504  *
3505  * Input:
3506  *	ha:	adapter state pointer.
3507  *	bp:	buffer pointer.
3508  *	size:	buffer size.
3509  *	opt:	command options.
3510  *	it_cnt:	iteration count.
3511  *	mr:	pointer for mailbox data.
3512  *
3513  * Returns:
3514  *	ql local function return status code.
3515  *
3516  * Context:
3517  *	Kernel context.
3518  */
3519 int
3520 ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
3521     uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3522 {
3523 	int		rval;
3524 	dma_mem_t	mem_desc;
3525 	mbx_cmd_t	mc = {0};
3526 	mbx_cmd_t	*mcp = &mc;
3527 
3528 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3529 
3530 
3531 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3532 	    QL_SUCCESS) {
3533 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3534 		return (rval);
3535 	}
3536 
3537 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3538 	mcp->mb[1] = opt;
3539 	mcp->mb[2] = 0;
3540 	mcp->mb[3] = 0;
3541 	mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3542 	mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3543 	mcp->mb[10] = LSW(size);
3544 	mcp->mb[11] = MSW(size);
3545 	mcp->mb[12] = 0;
3546 	mcp->mb[13] = 0;
3547 	mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3548 	mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3549 	mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3550 	mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3551 	mcp->mb[18] = LSW(it_cnt);
3552 	mcp->mb[19] = MSW(it_cnt);
3553 	mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3554 	mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3555 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3556 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
3557 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3558 	mcp->timeout = it_cnt / 300;
3559 	if (mcp->timeout < MAILBOX_TOV) {
3560 		mcp->timeout = MAILBOX_TOV;
3561 	}
3562 	rval = ql_mailbox_command(ha, mcp);
3563 
3564 	if (rval == QL_SUCCESS) {
3565 		ql_get_mbox_dma_data(&mem_desc, bp);
3566 	}
3567 
3568 	ql_free_dma_resource(ha, &mem_desc);
3569 
3570 	/* Return mailbox data. */
3571 	if (mr != NULL) {
3572 		mr->mb[0] = mcp->mb[0];
3573 		mr->mb[1] = mcp->mb[1];
3574 		mr->mb[2] = mcp->mb[2];
3575 		mr->mb[3] = mcp->mb[3];
3576 		mr->mb[18] = mcp->mb[18];
3577 		mr->mb[19] = mcp->mb[19];
3578 	}
3579 
3580 	if (rval != QL_SUCCESS) {
3581 		EL(ha, "failed=%xh, mb1=%xh\n", rval,
3582 		    mcp->mb[1]);
3583 	} else {
3584 		/*EMPTY*/
3585 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3586 	}
3587 
3588 	return (rval);
3589 }
3590 
3591 /*
3592  * ql_diag_echo
3593  *	Issue Diag echo mailbox command.  Valid for qla23xx HBA's.
3594  *
3595  * Input:
3596  *	ha:	adapter state pointer.
3597  *	bp:	buffer pointer.
3598  *	size:	buffer size.
3599  *	opt:	command options.
3600  *	mr:	pointer to mailbox status.
3601  *
3602  * Returns:
3603  *	ql local function return status code.
3604  *
3605  * Context:
3606  *	Kernel context.
3607  */
3608 int
3609 ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt,
3610     ql_mbx_data_t *mr)
3611 {
3612 	int		rval;
3613 	dma_mem_t	mem_desc;
3614 	mbx_cmd_t	mc = {0};
3615 	mbx_cmd_t	*mcp = &mc;
3616 
3617 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3618 
3619 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3620 	    QL_SUCCESS) {
3621 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3622 		return (rval);
3623 	}
3624 
3625 	mcp->mb[0] = MBC_ECHO;
3626 	mcp->mb[1] = opt;
3627 	mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3628 	mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3629 	mcp->mb[10] = LSW(size);
3630 	mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3631 	mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3632 	mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3633 	mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3634 	mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3635 	mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3636 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3637 	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
3638 	mcp->in_mb = MBX_1|MBX_0;
3639 	mcp->timeout = MAILBOX_TOV;
3640 	rval = ql_mailbox_command(ha, mcp);
3641 
3642 	if (rval == QL_SUCCESS) {
3643 		ql_get_mbox_dma_data(&mem_desc, bp);
3644 	}
3645 
3646 	ql_free_dma_resource(ha, &mem_desc);
3647 
3648 	if (mr != NULL) {
3649 		mr->mb[0] = mcp->mb[0];
3650 	}
3651 
3652 	if (rval != QL_SUCCESS) {
3653 		EL(ha, "failed=%xh, mb1=%xh\n", rval,
3654 		    mcp->mb[1]);
3655 	} else {
3656 		/*EMPTY*/
3657 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3658 	}
3659 
3660 	return (rval);
3661 }
3662 
3663 /*
3664  * ql_serdes_param
3665  *	Set/Get serdes transmit parameters mailbox command.
3666  *
3667  * Input:
3668  *	ha:	adapter state pointer.
3669  *	mr:	pointer to mailbox in/out parameters.
3670  *
3671  * Returns:
3672  *	ql local function return status code.
3673  *
3674  * Context:
3675  *	Kernel context.
3676  */
3677 int
3678 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3679 {
3680 	int		rval;
3681 	mbx_cmd_t	mc = {0};
3682 	mbx_cmd_t	*mcp = &mc;
3683 
3684 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3685 
3686 	mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
3687 	mcp->mb[1] = mr->mb[1];
3688 	mcp->mb[2] = mr->mb[2];
3689 	mcp->mb[3] = mr->mb[3];
3690 	mcp->mb[4] = mr->mb[4];
3691 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3692 	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
3693 	mcp->timeout = MAILBOX_TOV;
3694 	rval = ql_mailbox_command(ha, mcp);
3695 
3696 	/* Return mailbox data. */
3697 	if (mr != NULL) {
3698 		mr->mb[0] = mcp->mb[0];
3699 		mr->mb[2] = mcp->mb[2];
3700 		mr->mb[3] = mcp->mb[3];
3701 		mr->mb[4] = mcp->mb[4];
3702 	}
3703 
3704 	if (rval != QL_SUCCESS) {
3705 		EL(ha, "failed=%xh\n", rval);
3706 	} else {
3707 		/*EMPTY*/
3708 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3709 	}
3710 
3711 	return (rval);
3712 }
3713 
3714 /*
3715  * ql_get_timeout_parameters
3716  *	Issue get timeout parameters mailbox command.
3717  *
3718  * Input:
3719  *	ha:	adapter state pointer.
3720  *	mr:	pointer to mailbox in/out parameters.
3721  *
3722  * Returns:
3723  *	ql local function return status code.
3724  *
3725  * Context:
3726  *	Kernel context.
3727  */
3728 int
3729 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
3730 {
3731 	int		rval;
3732 	mbx_cmd_t	mc = {0};
3733 	mbx_cmd_t	*mcp = &mc;
3734 
3735 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3736 
3737 	mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
3738 	mcp->out_mb = MBX_0;
3739 	mcp->in_mb = MBX_3|MBX_0;
3740 	mcp->timeout = MAILBOX_TOV;
3741 	rval = ql_mailbox_command(ha, mcp);
3742 	if (rval == QL_SUCCESS) {
3743 		/* Get 2 * R_A_TOV in seconds */
3744 		if (CFG_IST(ha, CFG_CTRL_2200) || mcp->mb[3] == 0) {
3745 			*tov = R_A_TOV_DEFAULT;
3746 		} else {
3747 			*tov = (uint16_t)(mcp->mb[3] / 10);
3748 			if (mcp->mb[3] % 10 != 0) {
3749 				*tov = (uint16_t)(*tov + 1);
3750 			}
3751 			/*
3752 			 * Adjust value to prevent driver timeout at the same
3753 			 * time as device.
3754 			 */
3755 			*tov = (uint16_t)(*tov + 5);
3756 		}
3757 	} else {
3758 		*tov = R_A_TOV_DEFAULT;
3759 	}
3760 
3761 	if (rval != QL_SUCCESS) {
3762 		EL(ha, "failed=%xh\n", rval);
3763 	} else {
3764 		/*EMPTY*/
3765 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3766 	}
3767 
3768 	return (rval);
3769 }
3770 
3771 /*
3772  * ql_stop_firmware
3773  *	 Issue stop firmware Mailbox Command.
3774  *
3775  * Input:
3776  *	ha:	adapter state pointer.
3777  *
3778  * Returns:
3779  *	ql local function return status code.
3780  *
3781  * Context:
3782  *	Kernel context.
3783  */
3784 int
3785 ql_stop_firmware(ql_adapter_state_t *ha)
3786 {
3787 	int		rval;
3788 	mbx_cmd_t	mc = {0};
3789 	mbx_cmd_t	*mcp = &mc;
3790 
3791 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3792 
3793 	mcp->mb[0] = MBC_STOP_FIRMWARE;
3794 	mcp->out_mb = MBX_0;
3795 	mcp->in_mb = MBX_0;
3796 	mcp->timeout = MAILBOX_TOV;
3797 	rval = ql_mailbox_command(ha, mcp);
3798 
3799 	if (rval != QL_SUCCESS) {
3800 		EL(ha, "failed=%xh\n", rval);
3801 	} else {
3802 		/*EMPTY*/
3803 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3804 	}
3805 
3806 	return (rval);
3807 }
3808 
3809 /*
3810  * ql_read_sfp
3811  *	Issue Read SFP Mailbox command
3812  *
3813  * Input:
3814  *	ha:	adapter state pointer.
3815  *	mem:	pointer to dma memory object for command.
3816  *	dev:	Device address (A0h or A2h).
3817  *	addr:	Data address on SFP EEPROM (0�255).
3818  *
3819  * Returns:
3820  *	ql local function return status code.
3821  *
3822  * Context:
3823  *	Kernel context.
3824  */
3825 int
3826 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
3827     uint16_t addr)
3828 {
3829 	int		rval;
3830 	mbx_cmd_t	mc = {0};
3831 	mbx_cmd_t	*mcp = &mc;
3832 
3833 	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
3834 
3835 	mcp->mb[0] = MBC_READ_SFP;
3836 	mcp->mb[1] = dev;
3837 	mcp->mb[2] = MSW(mem->cookies->dmac_address);
3838 	mcp->mb[3] = LSW(mem->cookies->dmac_address);
3839 	mcp->mb[6] = MSW(mem->cookies->dmac_notused);
3840 	mcp->mb[7] = LSW(mem->cookies->dmac_notused);
3841 	mcp->mb[8] = LSW(mem->size);
3842 	mcp->mb[9] = addr;
3843 	mcp->mb[10] = 0;
3844 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3845 	mcp->in_mb = MBX_1|MBX_0;
3846 	mcp->timeout = MAILBOX_TOV;
3847 	rval = ql_mailbox_command(ha, mcp);
3848 
3849 	(void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
3850 	    DDI_DMA_SYNC_FORKERNEL);
3851 
3852 	if (rval != QL_SUCCESS) {
3853 		EL(ha, "failed=%xh\n", rval);
3854 	} else {
3855 		/*EMPTY*/
3856 		QL_PRINT_3(CE_CONT, "(%d): exiting\n", ha->instance);
3857 	}
3858 
3859 	return (rval);
3860 }
3861 
3862 /*
3863  * ql_iidma_rate
3864  *	Issue get/set iidma rate command
3865  *
3866  * Input:
3867  *	ha:		adapter state pointer.
3868  *	loop_id:	n-port handle to set/get iidma rate.
3869  *	idma_rate:	Pointer to iidma rate.
3870  *	option:		iidma firmware option (set or get data).
3871  *				0 --> Get iidma rate
3872  *				1 --> Set iidma rate
3873  *
3874  * Returns:
3875  *	ql local function return status code.
3876  *
3877  * Context:
3878  *	Kernel context.
3879  */
3880 int
3881 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
3882     uint32_t option)
3883 {
3884 	int		rval;
3885 	mbx_cmd_t	mc = {0};
3886 	mbx_cmd_t	*mcp = &mc;
3887 
3888 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3889 
3890 	mcp->mb[0] = MBC_PORT_PARAM;
3891 	mcp->mb[1] = loop_id;
3892 	mcp->mb[2] = (uint16_t)option;
3893 	mcp->out_mb = MBX_0|MBX_1|MBX_2;
3894 	mcp->in_mb = MBX_0|MBX_1;
3895 
3896 	if (option & BIT_0) {
3897 		mcp->mb[3] = (uint16_t)*idma_rate;
3898 		mcp->out_mb |= MBX_3;
3899 	} else {
3900 		mcp->in_mb |= MBX_3;
3901 	}
3902 
3903 	mcp->timeout = MAILBOX_TOV;
3904 	rval = ql_mailbox_command(ha, mcp);
3905 
3906 	if (rval != QL_SUCCESS) {
3907 		EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3908 	} else {
3909 		if (option == 0) {
3910 			*idma_rate = mcp->mb[3];
3911 		}
3912 
3913 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3914 	}
3915 
3916 	return (rval);
3917 }
3918 
3919 /*
3920  * ql_set_xmit_parms
3921  *	Set transmit parameters
3922  *
3923  * Input:
3924  *	ha:	adapter state pointer.
3925  *
3926  * Returns:
3927  *	ql local function return status code.
3928  *
3929  * Context:
3930  *	Kernel context.
3931  */
3932 int
3933 ql_set_xmit_parms(ql_adapter_state_t *ha)
3934 {
3935 	int		rval;
3936 	mbx_cmd_t	mc = {0};
3937 	mbx_cmd_t	*mcp = &mc;
3938 
3939 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3940 
3941 	mcp->mb[0] = MBC_XMIT_PARM;
3942 	mcp->mb[1] = BIT_1;
3943 	mcp->out_mb = MBX_1|MBX_0;
3944 	mcp->in_mb = MBX_0;
3945 	mcp->timeout = MAILBOX_TOV;
3946 	rval = ql_mailbox_command(ha, mcp);
3947 
3948 	if (rval != QL_SUCCESS) {
3949 		EL(ha, "failed=%xh\n", rval);
3950 	} else {
3951 		/*EMPTY*/
3952 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3953 	}
3954 	return (rval);
3955 }
3956 
3957 /*
3958  * ql_fw_etrace
3959  *	Firmware extended tracing.
3960  *
3961  * Input:
3962  *	ha:	adapter state pointer.
3963  *	mem:	pointer to dma memory object for command.
3964  *	opt:	options and opcode.
3965  *
3966  * Returns:
3967  *	ql local function return status code.
3968  *
3969  * Context:
3970  *	Kernel context.
3971  */
3972 int
3973 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt)
3974 {
3975 	int		rval = QL_SUCCESS;
3976 	mbx_cmd_t	mc = {0};
3977 	mbx_cmd_t	*mcp = &mc;
3978 	uint16_t	op_code;
3979 	uint64_t	time;
3980 
3981 	QL_PRINT_3(CE_CONT, "(%d): entered\n", ha->instance);
3982 
3983 	/* currently no supported options */
3984 	op_code = (uint16_t)(opt & ~0xFF00);
3985 
3986 	mcp->mb[0] = MBC_TRACE_CONTROL;
3987 	mcp->mb[1] = op_code;
3988 	mcp->in_mb = MBX_0;
3989 	mcp->timeout = MAILBOX_TOV;
3990 
3991 	switch (op_code) {
3992 	case FTO_INSERT_TIME_STAMP:
3993 
3994 		(void) drv_getparm(TIME, &time);
3995 
3996 		EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
3997 
3998 		mcp->mb[2] = LSW(LSD(time));
3999 		mcp->mb[3] = MSW(LSD(time));
4000 		mcp->mb[4] = LSW(MSD(time));
4001 		mcp->mb[5] = MSW(MSD(time));
4002 		mcp->out_mb = MBX_0_THRU_5;
4003 		break;
4004 
4005 	case FTO_FCE_TRACE_ENABLE:
4006 		/* Firmware Fibre Channel Event Trace Buffer */
4007 		mcp->mb[2] = LSW(mem->cookies->dmac_address);
4008 		mcp->mb[3] = MSW(mem->cookies->dmac_address);
4009 		mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4010 		mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4011 		mcp->mb[6] = (uint16_t)(mem->size / 0x4000);	/* 16kb blks */
4012 		mcp->mb[7] = 0;
4013 		mcp->mb[8] = (uint16_t)ha->fwfcetraceopt;
4014 		mcp->mb[9] = FTO_FCEMAXTRACEBUF;
4015 		mcp->mb[10] = FTO_FCEMAXTRACEBUF;
4016 		mcp->out_mb = MBX_0_THRU_10;
4017 		break;
4018 
4019 	case FTO_EXT_TRACE_ENABLE:
4020 		/* Firmware Extended Trace Buffer */
4021 		mcp->mb[2] = LSW(mem->cookies->dmac_address);
4022 		mcp->mb[3] = MSW(mem->cookies->dmac_address);
4023 		mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4024 		mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4025 		mcp->mb[6] = (uint16_t)(mem->size / 0x4000);	/* 16kb blks */
4026 		mcp->mb[7] = 0;
4027 		mcp->out_mb = MBX_0_THRU_7;
4028 		break;
4029 
4030 	case FTO_FCE_TRACE_DISABLE:
4031 		/* also causes ISP25xx to flush its internal FCE buffer. */
4032 		mcp->mb[2] = BIT_0;
4033 		mcp->out_mb = MBX_0_THRU_2;
4034 		break;
4035 
4036 	case FTO_EXT_TRACE_DISABLE:
4037 		/* just sending the opcode disables it */
4038 		break;
4039 
4040 	default:
4041 		EL(ha, "invalid option: %xh\n", opt);
4042 		rval = QL_PARAMETER_ERROR;
4043 		break;
4044 	}
4045 
4046 	if (rval == QL_SUCCESS) {
4047 		rval = ql_mailbox_command(ha, mcp);
4048 	}
4049 
4050 	if (rval != QL_SUCCESS) {
4051 		EL(ha, "failed=%xh\n", rval);
4052 	} else {
4053 		/*EMPTY*/
4054 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4055 	}
4056 
4057 	return (rval);
4058 }
4059 
4060 /*
4061  * ql_reset_menlo
4062  *	 Reset Menlo Mailbox Command.
4063  *
4064  * Input:
4065  *	ha:	adapter state pointer.
4066  *	mr:	pointer to mailbox in/out parameters.
4067  *	opt:	options.
4068  *
4069  * Returns:
4070  *	ql local function return status code.
4071  *
4072  * Context:
4073  *	Kernel context.
4074  */
4075 int
4076 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4077 {
4078 	int		rval;
4079 	mbx_cmd_t	mc = {0};
4080 	mbx_cmd_t	*mcp = &mc;
4081 
4082 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
4083 
4084 	mcp->mb[0] = MBC_RESET_MENLO;
4085 	mcp->mb[1] = opt;
4086 	mcp->out_mb = MBX_1|MBX_0;
4087 	mcp->in_mb = MBX_1|MBX_0;
4088 	mcp->timeout = MAILBOX_TOV;
4089 	rval = ql_mailbox_command(ha, mcp);
4090 
4091 	/* Return mailbox data. */
4092 	if (mr != NULL) {
4093 		mr->mb[0] = mcp->mb[0];
4094 		mr->mb[1] = mcp->mb[1];
4095 	}
4096 
4097 	if (rval != QL_SUCCESS) {
4098 		EL(ha, "failed=%xh\n", rval);
4099 	} else {
4100 		/*EMPTY*/
4101 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
4102 	}
4103 
4104 	return (rval);
4105 }
4106