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