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