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