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