1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /* Copyright 2010 QLogic Corporation */
23 
24 /*
25  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26  */
27 
28 #pragma ident	"Copyright 2010 QLogic Corporation; ql_mbx.c"
29 
30 /*
31  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32  *
33  * ***********************************************************************
34  * *									**
35  * *				NOTICE					**
36  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
37  * *			ALL RIGHTS RESERVED				**
38  * *									**
39  * ***********************************************************************
40  *
41  */
42 
43 #include <ql_apps.h>
44 #include <ql_api.h>
45 #include <ql_debug.h>
46 #include <ql_iocb.h>
47 #include <ql_isr.h>
48 #include <ql_mbx.h>
49 #include <ql_xioctl.h>
50 
51 /*
52  * Local data
53  */
54 
55 /*
56  * Local prototypes
57  */
58 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
59 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint16_t,
60     uint32_t, uint16_t);
61 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
62 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
63     caddr_t, uint32_t);
64 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
65     uint32_t);
66 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
67 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
68 
69 /*
70  * ql_mailbox_command
71  *	Issue mailbox command and waits for completion.
72  *
73  * Input:
74  *	ha = adapter state pointer.
75  *	mcp = mailbox command parameter structure pointer.
76  *
77  * Returns:
78  *	ql local function return status code.
79  *
80  * Context:
81  *	Kernel context.
82  */
83 static int
ql_mailbox_command(ql_adapter_state_t * vha,mbx_cmd_t * mcp)84 ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
85 {
86 	uint16_t		cnt;
87 	uint32_t		data;
88 	clock_t			timer, cv_stat;
89 	int			rval;
90 	uint32_t		set_flags = 0;
91 	uint32_t		reset_flags = 0;
92 	ql_adapter_state_t	*ha = vha->pha;
93 	int			mbx_cmd = mcp->mb[0];
94 
95 	QL_PRINT_3(CE_CONT, "(%d): started, cmd=%xh\n", ha->instance, mbx_cmd);
96 
97 	/* Acquire mailbox register lock. */
98 	MBX_REGISTER_LOCK(ha);
99 
100 	/* Check for mailbox available, if not wait for signal. */
101 	while (ha->mailbox_flags & MBX_BUSY_FLG ||
102 	    (CFG_IST(ha, CFG_CTRL_8021) &&
103 	    RD32_IO_REG(ha, nx_host_int) & NX_MBX_CMD)) {
104 		ha->mailbox_flags = (uint8_t)
105 		    (ha->mailbox_flags | MBX_WANT_FLG);
106 
107 		if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
108 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
109 			MBX_REGISTER_UNLOCK(ha);
110 			return (QL_LOCK_TIMEOUT);
111 		}
112 
113 		/* Set timeout after command that is running. */
114 		timer = (mcp->timeout + 20) * drv_usectohz(1000000);
115 		cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
116 		    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
117 		if (cv_stat == -1 || cv_stat == 0) {
118 			/*
119 			 * The timeout time 'timer' was
120 			 * reached without the condition
121 			 * being signaled.
122 			 */
123 			ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
124 			    ~MBX_WANT_FLG);
125 			cv_broadcast(&ha->cv_mbx_wait);
126 
127 			/* Release mailbox register lock. */
128 			MBX_REGISTER_UNLOCK(ha);
129 
130 			if (cv_stat == 0) {
131 				EL(vha, "waiting for availability aborted, "
132 				    "cmd=%xh\n", mcp->mb[0]);
133 				return (QL_ABORTED);
134 			}
135 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
136 			return (QL_LOCK_TIMEOUT);
137 		}
138 	}
139 
140 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
141 
142 	/* Structure pointer for return mailbox registers. */
143 	ha->mcp = mcp;
144 
145 	/* Load mailbox registers. */
146 	data = mcp->out_mb;
147 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
148 		if (data & MBX_0) {
149 			WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
150 		}
151 		data >>= 1;
152 	}
153 
154 	/* Issue set host interrupt command. */
155 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
156 	if (CFG_IST(ha, CFG_CTRL_8021)) {
157 		WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
158 	} else if (CFG_IST(ha, CFG_CTRL_242581)) {
159 		WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
160 	} else {
161 		WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
162 	}
163 
164 	/* Wait for command to complete. */
165 	if (ha->flags & INTERRUPTS_ENABLED &&
166 	    !(ha->task_daemon_flags & (TASK_THREAD_CALLED |
167 	    TASK_DAEMON_POWERING_DOWN)) &&
168 	    !ddi_in_panic()) {
169 		timer = mcp->timeout * drv_usectohz(1000000);
170 		while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
171 		    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
172 
173 			if (cv_reltimedwait(&ha->cv_mbx_intr,
174 			    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
175 				/*
176 				 * The timeout time 'timer' was
177 				 * reached without the condition
178 				 * being signaled.
179 				 */
180 				MBX_REGISTER_UNLOCK(ha);
181 				while (INTERRUPT_PENDING(ha)) {
182 					(void) ql_isr((caddr_t)ha);
183 					INTR_LOCK(ha);
184 					ha->intr_claimed = B_TRUE;
185 					INTR_UNLOCK(ha);
186 				}
187 				MBX_REGISTER_LOCK(ha);
188 				break;
189 			}
190 		}
191 	} else {
192 		/* Release mailbox register lock. */
193 		MBX_REGISTER_UNLOCK(ha);
194 
195 		/* Acquire interrupt lock. */
196 		for (timer = mcp->timeout * 100; timer; timer--) {
197 			/* Check for pending interrupts. */
198 			while (INTERRUPT_PENDING(ha)) {
199 				(void) ql_isr((caddr_t)ha);
200 				INTR_LOCK(ha);
201 				ha->intr_claimed = B_TRUE;
202 				INTR_UNLOCK(ha);
203 				if (ha->mailbox_flags &
204 				    (MBX_INTERRUPT | MBX_ABORT) ||
205 				    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
206 					break;
207 				}
208 			}
209 			if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
210 			    ha->task_daemon_flags & ISP_ABORT_NEEDED) {
211 				break;
212 			} else if (!ddi_in_panic() && timer % 101 == 0) {
213 				delay(drv_usectohz(10000));
214 			} else {
215 				drv_usecwait(10000);
216 			}
217 		}
218 
219 		/* Acquire mailbox register lock. */
220 		MBX_REGISTER_LOCK(ha);
221 	}
222 
223 	/* Mailbox command timeout? */
224 	if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
225 	    ha->mailbox_flags & MBX_ABORT) {
226 		rval = QL_ABORTED;
227 	} else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
228 		if (!CFG_IST(ha, CFG_CTRL_8021)) {
229 			if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
230 				(void) ql_binary_fw_dump(ha, FALSE);
231 			}
232 			EL(vha, "command timeout, isp_abort_needed\n");
233 			set_flags |= ISP_ABORT_NEEDED;
234 		}
235 		rval = QL_FUNCTION_TIMEOUT;
236 	} else {
237 		ha->mailbox_flags = (uint8_t)
238 		    (ha->mailbox_flags & ~MBX_INTERRUPT);
239 		/*
240 		 * This is the expected completion path so
241 		 * return the actual mbx cmd completion status.
242 		 */
243 		rval = mcp->mb[0];
244 	}
245 
246 	/*
247 	 * Clear outbound to risc mailbox registers per spec. The exception
248 	 * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
249 	 * so avoid writing them.
250 	 */
251 	if (ha->cfg_flags & CFG_CTRL_2200) {
252 		data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
253 	} else {
254 		data = (mcp->out_mb >> 1);
255 	}
256 	for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
257 		if (data & MBX_0) {
258 			WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
259 		}
260 		data >>= 1;
261 	}
262 
263 	/* Reset busy status. */
264 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
265 	    ~(MBX_BUSY_FLG | MBX_ABORT));
266 	ha->mcp = NULL;
267 
268 	/* If thread is waiting for mailbox go signal it to start. */
269 	if (ha->mailbox_flags & MBX_WANT_FLG) {
270 		ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
271 		    ~MBX_WANT_FLG);
272 		cv_broadcast(&ha->cv_mbx_wait);
273 	}
274 
275 	/* Release mailbox register lock. */
276 	MBX_REGISTER_UNLOCK(ha);
277 
278 	if (set_flags != 0 || reset_flags != 0) {
279 		ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
280 	}
281 
282 	if (rval != QL_SUCCESS) {
283 		EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
284 		    mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
285 	} else {
286 		/*EMPTY*/
287 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
288 	}
289 
290 	return (rval);
291 }
292 
293 /*
294  * ql_setup_mbox_dma_resources
295  *	Prepare the data for a mailbox dma transfer.
296  *
297  * Input:
298  *	ha = adapter state pointer.
299  *	mem_desc = descriptor to contain the dma resource information.
300  *	data = pointer to the data.
301  *	size = size of the data in bytes.
302  *
303  * Returns:
304  *	ql local function return status code.
305  *
306  * Context:
307  *	Kernel context.
308  */
309 static int
ql_setup_mbox_dma_transfer(ql_adapter_state_t * ha,dma_mem_t * mem_desc,caddr_t data,uint32_t size)310 ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
311     caddr_t data, uint32_t size)
312 {
313 	int rval = QL_SUCCESS;
314 
315 	if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) ==
316 	    QL_SUCCESS) {
317 		ql_setup_mbox_dma_data(mem_desc, data);
318 	} else {
319 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
320 	}
321 
322 	return (rval);
323 }
324 
325 /*
326  * ql_setup_mbox_dma_resources
327  *	Prepare a dma buffer.
328  *
329  * Input:
330  *	ha = adapter state pointer.
331  *	mem_desc = descriptor to contain the dma resource information.
332  *	data = pointer to the data.
333  *	size = size of the data in bytes.
334  *
335  * Returns:
336  *	ql local function return status code.
337  *
338  * Context:
339  *	Kernel context.
340  */
341 static int
ql_setup_mbox_dma_resources(ql_adapter_state_t * ha,dma_mem_t * mem_desc,uint32_t size)342 ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
343     uint32_t size)
344 {
345 	int	rval = QL_SUCCESS;
346 
347 	if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA,
348 	    QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
349 		EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n");
350 		rval = QL_MEMORY_ALLOC_FAILED;
351 	}
352 
353 	return (rval);
354 }
355 
356 /*
357  * ql_setup_mbox_dma_data
358  *	Move data to the dma buffer.
359  *
360  * Input:
361  *	mem_desc = descriptor to contain the dma resource information.
362  *	data = pointer to the data.
363  *
364  * Returns:
365  *
366  * Context:
367  *	Kernel context.
368  */
369 static void
ql_setup_mbox_dma_data(dma_mem_t * mem_desc,caddr_t data)370 ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
371 {
372 	/* Copy out going data to DMA buffer. */
373 	ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data,
374 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
375 
376 	/* Sync DMA buffer. */
377 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
378 	    DDI_DMA_SYNC_FORDEV);
379 }
380 
381 /*
382  * ql_get_mbox_dma_data
383  *	Recover data from the dma buffer.
384  *
385  * Input:
386  *	mem_desc = descriptor to contain the dma resource information.
387  *	data = pointer to the data.
388  *
389  * Returns:
390  *
391  * Context:
392  *	Kernel context.
393  */
394 static void
ql_get_mbox_dma_data(dma_mem_t * mem_desc,caddr_t data)395 ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
396 {
397 	/* Sync in coming DMA buffer. */
398 	(void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
399 	    DDI_DMA_SYNC_FORKERNEL);
400 	/* Copy in coming DMA data. */
401 	ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data,
402 	    (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
403 }
404 
405 /*
406  * ql_initialize_ip
407  *	Initialize IP receive buffer queue.
408  *
409  * Input:
410  *	ha = adapter state pointer.
411  *	ha->ip_init_ctrl_blk = setup for transmit.
412  *
413  * Returns:
414  *	ql local function return status code.
415  *
416  * Context:
417  *	Kernel context.
418  */
419 int
ql_initialize_ip(ql_adapter_state_t * ha)420 ql_initialize_ip(ql_adapter_state_t *ha)
421 {
422 	ql_link_t	*link;
423 	ql_tgt_t	*tq;
424 	uint16_t	index;
425 	int		rval;
426 	dma_mem_t	mem_desc;
427 	mbx_cmd_t	mc = {0};
428 	mbx_cmd_t	*mcp = &mc;
429 
430 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
431 
432 	if (CFG_IST(ha, (CFG_CTRL_6322 | CFG_CTRL_258081)) ||
433 	    ha->vp_index != 0) {
434 		ha->flags &= ~IP_INITIALIZED;
435 		EL(ha, "HBA does not support IP\n");
436 		return (QL_FUNCTION_FAILED);
437 	}
438 
439 	ha->rcvbuf_ring_ptr = ha->rcvbuf_ring_bp;
440 	ha->rcvbuf_ring_index = 0;
441 
442 	/* Reset all sequence counts. */
443 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
444 		for (link = ha->dev[index].first; link != NULL;
445 		    link = link->next) {
446 			tq = link->base_address;
447 			tq->ub_total_seg_cnt = 0;
448 		}
449 	}
450 
451 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
452 	    (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
453 	if (rval != QL_SUCCESS) {
454 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
455 		return (rval);
456 	}
457 
458 	mcp->mb[0] = MBC_INITIALIZE_IP;
459 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
460 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
461 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
462 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
463 	mcp->mb[8] = 0;
464 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
465 	mcp->in_mb = MBX_8|MBX_0;
466 	mcp->timeout = MAILBOX_TOV;
467 	rval = ql_mailbox_command(ha, mcp);
468 
469 	ql_free_dma_resource(ha, &mem_desc);
470 
471 	if (rval == QL_SUCCESS) {
472 		ADAPTER_STATE_LOCK(ha);
473 		ha->flags |= IP_INITIALIZED;
474 		ADAPTER_STATE_UNLOCK(ha);
475 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
476 	} else {
477 		ha->flags &= ~IP_INITIALIZED;
478 		EL(ha, "failed, rval = %xh\n", rval);
479 	}
480 	return (rval);
481 }
482 
483 /*
484  * ql_shutdown_ip
485  *	Disconnects firmware IP from system buffers.
486  *
487  * Input:
488  *	ha = adapter state pointer.
489  *
490  * Returns:
491  *	ql local function return status code.
492  *
493  * Context:
494  *	Kernel context.
495  */
496 int
ql_shutdown_ip(ql_adapter_state_t * ha)497 ql_shutdown_ip(ql_adapter_state_t *ha)
498 {
499 	int		rval;
500 	mbx_cmd_t	mc = {0};
501 	mbx_cmd_t	*mcp = &mc;
502 	fc_unsol_buf_t	*ubp;
503 	ql_srb_t	*sp;
504 	uint16_t	index;
505 
506 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
507 
508 	mcp->mb[0] = MBC_UNLOAD_IP;
509 	mcp->out_mb = MBX_0;
510 	mcp->in_mb = MBX_0;
511 	mcp->timeout = MAILBOX_TOV;
512 	rval = ql_mailbox_command(ha, mcp);
513 
514 	ADAPTER_STATE_LOCK(ha);
515 	QL_UB_LOCK(ha);
516 	/* Return all unsolicited buffers that ISP-IP has. */
517 	for (index = 0; index < QL_UB_LIMIT; index++) {
518 		ubp = ha->ub_array[index];
519 		if (ubp != NULL) {
520 			sp = ubp->ub_fca_private;
521 			sp->flags &= ~SRB_UB_IN_ISP;
522 		}
523 	}
524 
525 	ha->ub_outcnt = 0;
526 	QL_UB_UNLOCK(ha);
527 	ha->flags &= ~IP_INITIALIZED;
528 	ADAPTER_STATE_UNLOCK(ha);
529 
530 	if (rval == QL_SUCCESS) {
531 		/* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
532 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
533 	} else {
534 		EL(ha, "failed, rval = %xh\n", rval);
535 	}
536 	return (rval);
537 }
538 
539 /*
540  * ql_online_selftest
541  *	Issue online self test mailbox command.
542  *
543  * Input:
544  *	ha = adapter state pointer.
545  *
546  * Returns:
547  *	ql local function return status code.
548  *
549  * Context:
550  *	Kernel context.
551  */
552 int
ql_online_selftest(ql_adapter_state_t * ha)553 ql_online_selftest(ql_adapter_state_t *ha)
554 {
555 	int		rval;
556 	mbx_cmd_t	mc = {0};
557 	mbx_cmd_t	*mcp = &mc;
558 
559 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
560 
561 	mcp->mb[0] = MBC_ONLINE_SELF_TEST;
562 	mcp->out_mb = MBX_0;
563 	mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
564 	mcp->timeout = MAILBOX_TOV;
565 	rval = ql_mailbox_command(ha, mcp);
566 
567 	if (rval != QL_SUCCESS) {
568 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
569 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
570 	} else {
571 		/*EMPTY*/
572 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
573 	}
574 	return (rval);
575 }
576 
577 /*
578  * ql_loop_back
579  *	Issue diagnostic loop back frame mailbox command.
580  *
581  * Input:
582  *	ha:	adapter state pointer.
583  *	findex:	FCF index.
584  *	lb:	loop back parameter structure pointer.
585  *
586  * Returns:
587  *	ql local function return status code.
588  *
589  * Context:
590  *	Kernel context.
591  */
592 #ifndef apps_64bit
593 int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb,uint32_t h_xmit,uint32_t h_rcv)594 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
595     uint32_t h_xmit, uint32_t h_rcv)
596 {
597 	int		rval;
598 	mbx_cmd_t	mc = {0};
599 	mbx_cmd_t	*mcp = &mc;
600 
601 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
602 
603 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
604 	mcp->mb[1] = lb->options;
605 	mcp->mb[2] = findex;
606 	mcp->mb[6] = LSW(h_rcv);
607 	mcp->mb[7] = MSW(h_rcv);
608 	mcp->mb[10] = LSW(lb->transfer_count);
609 	mcp->mb[11] = MSW(lb->transfer_count);
610 	mcp->mb[12] = lb->transfer_segment_count;
611 	mcp->mb[13] = lb->receive_segment_count;
612 	mcp->mb[14] = LSW(lb->transfer_data_address);
613 	mcp->mb[15] = MSW(lb->transfer_data_address);
614 	mcp->mb[16] = LSW(lb->receive_data_address);
615 	mcp->mb[17] = MSW(lb->receive_data_address);
616 	mcp->mb[18] = LSW(lb->iteration_count);
617 	mcp->mb[19] = MSW(lb->iteration_count);
618 	mcp->mb[20] = LSW(h_xmit);
619 	mcp->mb[21] = MSW(h_xmit);
620 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
621 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
622 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
623 	mcp->timeout = lb->iteration_count / 300;
624 
625 	if (mcp->timeout < MAILBOX_TOV) {
626 		mcp->timeout = MAILBOX_TOV;
627 	}
628 
629 	rval = ql_mailbox_command(ha, mcp);
630 
631 	if (rval != QL_SUCCESS) {
632 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
633 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
634 	} else {
635 		/*EMPTY*/
636 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
637 	}
638 	return (rval);
639 }
640 #else
641 int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb)642 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
643 {
644 	int		rval;
645 	mbx_cmd_t	mc = {0};
646 	mbx_cmd_t	*mcp = &mc;
647 
648 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
649 
650 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
651 	mcp->mb[1] = lb->options;
652 	mcp->mb[2] = findex;
653 	mcp->mb[6] = LSW(h_rcv);
654 	mcp->mb[7] = MSW(h_rcv);
655 	mcp->mb[6] = LSW(MSD(lb->receive_data_address));
656 	mcp->mb[7] = MSW(MSD(lb->receive_data_address));
657 	mcp->mb[10] = LSW(lb->transfer_count);
658 	mcp->mb[11] = MSW(lb->transfer_count);
659 	mcp->mb[12] = lb->transfer_segment_count;
660 	mcp->mb[13] = lb->receive_segment_count;
661 	mcp->mb[14] = LSW(lb->transfer_data_address);
662 	mcp->mb[15] = MSW(lb->transfer_data_address);
663 	mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
664 	mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
665 	mcp->mb[16] = LSW(lb->receive_data_address);
666 	mcp->mb[17] = MSW(lb->receive_data_address);
667 	mcp->mb[16] = LSW(LSD(lb->receive_data_address));
668 	mcp->mb[17] = MSW(LSD(lb->receive_data_address));
669 	mcp->mb[18] = LSW(lb->iteration_count);
670 	mcp->mb[19] = MSW(lb->iteration_count);
671 	mcp->mb[20] = LSW(h_xmit);
672 	mcp->mb[21] = MSW(h_xmit);
673 	mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
674 	mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
675 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
676 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
677 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
678 	mcp->timeout = lb->iteration_count / 300;
679 
680 	if (mcp->timeout < MAILBOX_TOV) {
681 		mcp->timeout = MAILBOX_TOV;
682 	}
683 
684 	rval = ql_mailbox_command(ha, mcp);
685 
686 	if (rval != QL_SUCCESS) {
687 		EL(ha, "failed, rval = %xh\n", rval);
688 	} else {
689 		/*EMPTY*/
690 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
691 	}
692 	return (rval);
693 }
694 #endif
695 
696 /*
697  * ql_echo
698  *	Issue an ELS echo using the user specified data to a user specified
699  *	destination
700  *
701  * Input:
702  *	ha:		adapter state pointer.
703  *	findex:		FCF index.
704  *	echo_pt:	echo parameter structure pointer.
705  *
706  * Returns:
707  *	ql local function return status code.
708  *
709  * Context:
710  *	Kernel context.
711  */
712 int
ql_echo(ql_adapter_state_t * ha,uint16_t findex,echo_t * echo_pt)713 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
714 {
715 	int		rval;
716 	mbx_cmd_t	mc = {0};
717 	mbx_cmd_t	*mcp = &mc;
718 
719 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
720 
721 	mcp->mb[0] = MBC_ECHO;			/* ECHO command */
722 	mcp->mb[1] = echo_pt->options;		/* command options; 64 bit */
723 						/* addressing (bit 6) and */
724 						/* real echo (bit 15 */
725 	mcp->mb[2] = findex;
726 
727 	/*
728 	 * I know this looks strange, using a field labled "not used"
729 	 * The way the ddi_dma_cookie_t structure/union is defined
730 	 * is a union of one 64 bit entity with an array of two 32
731 	 * bit enititys.  Since we have routines to convert 32 bit
732 	 * entities into 16 bit entities it is easier to use
733 	 * both 32 bit union members then the one 64 bit union
734 	 * member
735 	 */
736 	if (echo_pt->options & BIT_6) {
737 		/* 64 bit addressing */
738 		/* Receive data dest add in system memory bits 47-32 */
739 		mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
740 
741 		/* Receive data dest add in system memory bits 63-48 */
742 		mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
743 
744 		/* Transmit data source address in system memory bits 47-32 */
745 		mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
746 
747 		/* Transmit data source address in system memory bits 63-48 */
748 		mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
749 	}
750 
751 	/* transfer count bits 15-0 */
752 	mcp->mb[10] = LSW(echo_pt->transfer_count);
753 
754 	/* Transmit data source address in system memory bits 15-0 */
755 	mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
756 
757 	/*  Transmit data source address in system memory bits 31-16 */
758 	mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
759 
760 	/* Receive data destination address in system memory bits 15-0 */
761 	mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
762 
763 	/*  Receive data destination address in system memory bits 31-16 */
764 	mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
765 
766 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
767 	    MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
768 	mcp->in_mb = MBX_3|MBX_1|MBX_0;
769 	mcp->timeout = MAILBOX_TOV;
770 
771 	rval = ql_mailbox_command(ha, mcp);
772 
773 	if (rval != QL_SUCCESS) {
774 		EL(ha, "failed, rval = %xh\n", rval);
775 	} else {
776 		/*EMPTY*/
777 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
778 	}
779 	return (rval);
780 }
781 
782 /*
783  * ql_send_change_request
784  *	Issue send change request mailbox command.
785  *
786  * Input:
787  *	ha:	adapter state pointer.
788  *	fmt:	Registration format.
789  *
790  * Returns:
791  *	ql local function return status code.
792  *
793  * Context:
794  *	Kernel context.
795  */
796 int
ql_send_change_request(ql_adapter_state_t * ha,uint16_t fmt)797 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
798 {
799 	int		rval;
800 	mbx_cmd_t	mc = {0};
801 	mbx_cmd_t	*mcp = &mc;
802 
803 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
804 
805 	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
806 	mcp->mb[1] = fmt;
807 	mcp->out_mb = MBX_1|MBX_0;
808 	if (ha->flags & VP_ENABLED) {
809 		mcp->mb[9] = ha->vp_index;
810 		mcp->out_mb |= MBX_9;
811 	}
812 	mcp->in_mb = MBX_0;
813 	mcp->timeout = MAILBOX_TOV;
814 	rval = ql_mailbox_command(ha, mcp);
815 
816 	if (rval != QL_SUCCESS) {
817 		EL(ha, "failed=%xh\n", rval);
818 	} else {
819 		/*EMPTY*/
820 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
821 	}
822 	return (rval);
823 }
824 
825 /*
826  * ql_send_lfa
827  *	Send a Loop Fabric Address mailbox command.
828  *
829  * Input:
830  *	ha:	adapter state pointer.
831  *	lfa:	LFA command structure pointer.
832  *
833  * Returns:
834  *	ql local function return status code.
835  *
836  * Context:
837  *	Kernel context.
838  */
839 int
ql_send_lfa(ql_adapter_state_t * ha,lfa_cmd_t * lfa)840 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
841 {
842 	int		rval;
843 	uint16_t	size;
844 	dma_mem_t	mem_desc;
845 	mbx_cmd_t	mc = {0};
846 	mbx_cmd_t	*mcp = &mc;
847 
848 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
849 
850 	/* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
851 	size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
852 
853 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
854 	if (rval != QL_SUCCESS) {
855 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
856 		return (rval);
857 	}
858 
859 	mcp->mb[0] = MBC_SEND_LFA_COMMAND;
860 	mcp->mb[1] = (uint16_t)(size >> 1);
861 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
862 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
863 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
864 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
865 	mcp->in_mb = MBX_0;
866 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
867 	if (ha->flags & VP_ENABLED) {
868 		mcp->mb[9] = ha->vp_index;
869 		mcp->out_mb |= MBX_9;
870 	}
871 	mcp->timeout = MAILBOX_TOV;
872 	rval = ql_mailbox_command(ha, mcp);
873 
874 	ql_free_dma_resource(ha, &mem_desc);
875 
876 	if (rval != QL_SUCCESS) {
877 		EL(ha, "failed, rval = %xh\n", rval);
878 	} else {
879 		/*EMPTY*/
880 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
881 	}
882 
883 	return (rval);
884 }
885 
886 /*
887  * ql_clear_aca
888  *	Issue clear ACA mailbox command.
889  *
890  * Input:
891  *	ha:	adapter state pointer.
892  *	tq:	target queue pointer.
893  *	lun:	LUN.
894  *
895  * Returns:
896  *	ql local function return status code.
897  *
898  * Context:
899  *	Kernel context.
900  */
901 int
ql_clear_aca(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t lun)902 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
903 {
904 	int		rval;
905 	mbx_cmd_t	mc = {0};
906 	mbx_cmd_t	*mcp = &mc;
907 
908 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
909 
910 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
911 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_ACA, 0);
912 	} else {
913 		mcp->mb[0] = MBC_CLEAR_ACA;
914 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
915 			mcp->mb[1] = tq->loop_id;
916 		} else {
917 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
918 		}
919 		mcp->mb[2] = lun;
920 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
921 		mcp->in_mb = MBX_0;
922 		mcp->timeout = MAILBOX_TOV;
923 		rval = ql_mailbox_command(ha, mcp);
924 	}
925 
926 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
927 
928 	if (rval != QL_SUCCESS) {
929 		EL(ha, "failed, rval = %xh\n", rval);
930 	} else {
931 		/*EMPTY*/
932 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
933 	}
934 
935 	return (rval);
936 }
937 
938 /*
939  * ql_target_reset
940  *	Issue target reset mailbox command.
941  *
942  * Input:
943  *	ha:	adapter state pointer.
944  *	tq:	target queue pointer.
945  *	delay:	seconds.
946  *
947  * Returns:
948  *	ql local function return status code.
949  *
950  * Context:
951  *	Kernel context.
952  */
953 int
ql_target_reset(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t delay)954 ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
955 {
956 	ql_link_t	*link;
957 	uint16_t	index;
958 	int		rval;
959 	mbx_cmd_t	mc = {0};
960 	mbx_cmd_t	*mcp = &mc;
961 
962 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
963 
964 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
965 		/* queue = NULL, all targets. */
966 		if (tq == NULL) {
967 			for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
968 			    index++) {
969 				for (link = ha->dev[index].first; link !=
970 				    NULL; link = link->next) {
971 					tq = link->base_address;
972 					if (!VALID_DEVICE_ID(ha,
973 					    tq->loop_id)) {
974 						continue;
975 					}
976 
977 					if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
978 						rval = ql_task_mgmt_iocb(ha,
979 						    tq, 0, CF_DO_NOT_SEND |
980 						    CF_TARGET_RESET, delay);
981 					} else {
982 						rval = ql_task_mgmt_iocb(ha,
983 						    tq, 0, CF_TARGET_RESET,
984 						    delay);
985 					}
986 
987 					if (rval != QL_SUCCESS) {
988 						break;
989 					}
990 				}
991 
992 				if (link != NULL) {
993 					break;
994 				}
995 			}
996 			tq = NULL;
997 		} else {
998 
999 			if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1000 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1001 				    CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
1002 			} else {
1003 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1004 				    CF_TARGET_RESET, delay);
1005 			}
1006 		}
1007 	} else {
1008 		/* queue = NULL, all targets. */
1009 		if (tq == NULL) {
1010 			mcp->mb[0] = MBC_RESET;
1011 			mcp->mb[1] = delay;
1012 			mcp->out_mb = MBX_1|MBX_0;
1013 		} else {
1014 			mcp->mb[0] = MBC_TARGET_RESET;
1015 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1016 				mcp->mb[1] = tq->loop_id;
1017 			} else {
1018 				mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1019 			}
1020 			mcp->mb[2] = delay;
1021 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1022 		}
1023 		mcp->in_mb = MBX_0;
1024 		mcp->timeout = MAILBOX_TOV;
1025 		rval = ql_mailbox_command(ha, mcp);
1026 	}
1027 
1028 	tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1029 	    (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1030 
1031 	if (rval != QL_SUCCESS) {
1032 		EL(ha, "failed, rval = %xh\n", rval);
1033 	} else {
1034 		/*EMPTY*/
1035 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1036 	}
1037 
1038 	return (rval);
1039 }
1040 
1041 /*
1042  * ql_abort_target
1043  *	Issue abort target mailbox command.
1044  *
1045  * Input:
1046  *	ha:	adapter state pointer.
1047  *	tq:	target queue pointer.
1048  *	delay:	in seconds.
1049  *
1050  * Returns:
1051  *	ql local function return status code.
1052  *
1053  * Context:
1054  *	Kernel context.
1055  */
1056 int
ql_abort_target(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t delay)1057 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1058 {
1059 	int		rval;
1060 	mbx_cmd_t	mc = {0};
1061 	mbx_cmd_t	*mcp = &mc;
1062 
1063 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1064 
1065 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1066 		rval = ql_task_mgmt_iocb(ha, tq, 0,
1067 		    CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1068 	} else {
1069 		mcp->mb[0] = MBC_ABORT_TARGET;
1070 		/* Don't send Task Mgt */
1071 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1072 			mcp->mb[1] = tq->loop_id;
1073 			mcp->mb[10] = BIT_0;
1074 			mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1075 		} else {
1076 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1077 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1078 		}
1079 		mcp->mb[2] = delay;
1080 		mcp->in_mb = MBX_0;
1081 		mcp->timeout = MAILBOX_TOV;
1082 		rval = ql_mailbox_command(ha, mcp);
1083 	}
1084 
1085 	(void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1086 
1087 	if (rval != QL_SUCCESS) {
1088 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1089 	} else {
1090 		/*EMPTY*/
1091 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1092 	}
1093 	return (rval);
1094 }
1095 
1096 /*
1097  * ql_lun_reset
1098  *	Issue LUN reset task management mailbox command.
1099  *
1100  * Input:
1101  *	ha:	adapter state pointer.
1102  *	tq:	target queue pointer.
1103  *	lun:	LUN.
1104  *
1105  * Returns:
1106  *	ql local function return status code.
1107  *
1108  * Context:
1109  *	Kernel context.
1110  */
1111 int
ql_lun_reset(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t lun)1112 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1113 {
1114 	int		rval;
1115 	mbx_cmd_t	mc = {0};
1116 	mbx_cmd_t	*mcp = &mc;
1117 
1118 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1119 
1120 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1121 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_LUN_RESET, 0);
1122 	} else {
1123 		mcp->mb[0] = MBC_LUN_RESET;
1124 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1125 			mcp->mb[1] = tq->loop_id;
1126 		} else {
1127 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1128 		}
1129 		mcp->mb[2] = lun;
1130 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1131 		mcp->in_mb = MBX_0;
1132 		mcp->timeout = MAILBOX_TOV;
1133 		rval = ql_mailbox_command(ha, mcp);
1134 	}
1135 
1136 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1137 
1138 	if (rval != QL_SUCCESS) {
1139 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1140 	} else {
1141 		/*EMPTY*/
1142 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1143 	}
1144 	return (rval);
1145 }
1146 
1147 /*
1148  * ql_clear_task_set
1149  *	Issue clear task set mailbox command.
1150  *
1151  * Input:
1152  *	ha:	adapter state pointer.
1153  *	tq:	target queue pointer.
1154  *	lun:	LUN.
1155  *
1156  * Returns:
1157  *	ql local function return status code.
1158  *
1159  * Context:
1160  *	Kernel context.
1161  */
1162 int
ql_clear_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t lun)1163 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1164 {
1165 	int		rval;
1166 	mbx_cmd_t	mc = {0};
1167 	mbx_cmd_t	*mcp = &mc;
1168 
1169 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1170 
1171 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1172 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_CLEAR_TASK_SET, 0);
1173 	} else {
1174 		mcp->mb[0] = MBC_CLEAR_TASK_SET;
1175 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1176 			mcp->mb[1] = tq->loop_id;
1177 		} else {
1178 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1179 		}
1180 		mcp->mb[2] = lun;
1181 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1182 		mcp->in_mb = MBX_0;
1183 		mcp->timeout = MAILBOX_TOV;
1184 		rval = ql_mailbox_command(ha, mcp);
1185 	}
1186 
1187 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1188 
1189 	if (rval != QL_SUCCESS) {
1190 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1191 	} else {
1192 		/*EMPTY*/
1193 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1194 	}
1195 
1196 	return (rval);
1197 }
1198 
1199 /*
1200  * ql_abort_task_set
1201  *	Issue abort task set mailbox command.
1202  *
1203  * Input:
1204  *	ha:	adapter state pointer.
1205  *	tq:	target queue pointer.
1206  *	lun:	LUN.
1207  *
1208  * Returns:
1209  *	ql local function return status code.
1210  *
1211  * Context:
1212  *	Kernel context.
1213  */
1214 int
ql_abort_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t lun)1215 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun)
1216 {
1217 	int		rval;
1218 	mbx_cmd_t	mc = {0};
1219 	mbx_cmd_t	*mcp = &mc;
1220 
1221 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1222 
1223 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1224 		rval = ql_task_mgmt_iocb(ha, tq, lun, CF_ABORT_TASK_SET, 0);
1225 	} else {
1226 		mcp->mb[0] = MBC_ABORT_TASK_SET;
1227 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1228 			mcp->mb[1] = tq->loop_id;
1229 		} else {
1230 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1231 		}
1232 		mcp->mb[2] = lun;
1233 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1234 		mcp->in_mb = MBX_0;
1235 		mcp->timeout = MAILBOX_TOV;
1236 		rval = ql_mailbox_command(ha, mcp);
1237 	}
1238 
1239 	(void) ql_marker(ha, tq->loop_id, lun, MK_SYNC_ID);
1240 
1241 	if (rval != QL_SUCCESS) {
1242 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1243 	} else {
1244 		/*EMPTY*/
1245 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1246 	}
1247 
1248 	return (rval);
1249 }
1250 
1251 /*
1252  * ql_task_mgmt_iocb
1253  *	Function issues task management IOCB.
1254  *
1255  * Input:
1256  *	ha:	adapter state pointer.
1257  *	tq:	target queue pointer.
1258  *	lun:	LUN.
1259  *	flags:	control flags.
1260  *	delay:	seconds.
1261  *
1262  * Returns:
1263  *	ql local function return status code.
1264  *
1265  * Context:
1266  *	Kernel context
1267  */
1268 static int
ql_task_mgmt_iocb(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t lun,uint32_t flags,uint16_t delay)1269 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t lun,
1270     uint32_t flags, uint16_t delay)
1271 {
1272 	ql_mbx_iocb_t	*pkt;
1273 	int		rval;
1274 	uint32_t	pkt_size;
1275 
1276 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1277 
1278 	pkt_size = sizeof (ql_mbx_iocb_t);
1279 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1280 	if (pkt == NULL) {
1281 		EL(ha, "failed, kmem_zalloc\n");
1282 		return (QL_MEMORY_ALLOC_FAILED);
1283 	}
1284 
1285 	pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1286 	pkt->mgmt.entry_count = 1;
1287 
1288 	pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1289 	pkt->mgmt.delay = (uint16_t)LE_16(delay);
1290 	pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1291 	pkt->mgmt.fcp_lun[2] = LSB(lun);
1292 	pkt->mgmt.fcp_lun[3] = MSB(lun);
1293 	pkt->mgmt.control_flags = LE_32(flags);
1294 	pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1295 	pkt->mgmt.target_id[1] = tq->d_id.b.area;
1296 	pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1297 	pkt->mgmt.vp_index = ha->vp_index;
1298 
1299 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1300 	if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1301 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1302 		    pkt->sts24.entry_status, tq->d_id.b24);
1303 		rval = QL_FUNCTION_PARAMETER_ERROR;
1304 	}
1305 
1306 	LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1307 
1308 	if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1309 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1310 		    pkt->sts24.comp_status, tq->d_id.b24);
1311 		rval = QL_FUNCTION_FAILED;
1312 	}
1313 
1314 	kmem_free(pkt, pkt_size);
1315 
1316 	if (rval != QL_SUCCESS) {
1317 		EL(ha, "failed, rval = %xh\n", rval);
1318 	} else {
1319 		/*EMPTY*/
1320 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1321 	}
1322 
1323 	return (rval);
1324 }
1325 
1326 /*
1327  * ql_loop_port_bypass
1328  *	Issue loop port bypass mailbox command.
1329  *
1330  * Input:
1331  *	ha:	adapter state pointer.
1332  *	tq:	target queue pointer.
1333  *
1334  * Returns:
1335  *	ql local function return status code.
1336  *
1337  * Context:
1338  *	Kernel context.
1339  */
1340 int
ql_loop_port_bypass(ql_adapter_state_t * ha,ql_tgt_t * tq)1341 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1342 {
1343 	int		rval;
1344 	mbx_cmd_t	mc = {0};
1345 	mbx_cmd_t	*mcp = &mc;
1346 
1347 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1348 
1349 	mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1350 
1351 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1352 		mcp->mb[1] = tq->d_id.b.al_pa;
1353 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1354 		mcp->mb[1] = tq->loop_id;
1355 	} else {
1356 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1357 	}
1358 
1359 	mcp->out_mb = MBX_1|MBX_0;
1360 	mcp->in_mb = MBX_0;
1361 	mcp->timeout = MAILBOX_TOV;
1362 	rval = ql_mailbox_command(ha, mcp);
1363 
1364 	if (rval != QL_SUCCESS) {
1365 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1366 	} else {
1367 		/*EMPTY*/
1368 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1369 	}
1370 
1371 	return (rval);
1372 }
1373 
1374 /*
1375  * ql_loop_port_enable
1376  *	Issue loop port enable mailbox command.
1377  *
1378  * Input:
1379  *	ha:	adapter state pointer.
1380  *	tq:	target queue pointer.
1381  *
1382  * Returns:
1383  *	ql local function return status code.
1384  *
1385  * Context:
1386  *	Kernel context.
1387  */
1388 int
ql_loop_port_enable(ql_adapter_state_t * ha,ql_tgt_t * tq)1389 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1390 {
1391 	int		rval;
1392 	mbx_cmd_t	mc = {0};
1393 	mbx_cmd_t	*mcp = &mc;
1394 
1395 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1396 
1397 	mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1398 
1399 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1400 		mcp->mb[1] = tq->d_id.b.al_pa;
1401 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1402 		mcp->mb[1] = tq->loop_id;
1403 	} else {
1404 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1405 	}
1406 	mcp->out_mb = MBX_1|MBX_0;
1407 	mcp->in_mb = MBX_0;
1408 	mcp->timeout = MAILBOX_TOV;
1409 	rval = ql_mailbox_command(ha, mcp);
1410 
1411 	if (rval != QL_SUCCESS) {
1412 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1413 	} else {
1414 		/*EMPTY*/
1415 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1416 	}
1417 
1418 	return (rval);
1419 }
1420 
1421 /*
1422  * ql_login_lport
1423  *	Issue login loop port mailbox command.
1424  *
1425  * Input:
1426  *	ha:		adapter state pointer.
1427  *	tq:		target queue pointer.
1428  *	loop_id:	FC loop id.
1429  *	opt:		options.
1430  *			LLF_NONE, LLF_PLOGI
1431  *
1432  * Returns:
1433  *	ql local function return status code.
1434  *
1435  * Context:
1436  *	Kernel context.
1437  */
1438 int
ql_login_lport(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t opt)1439 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1440     uint16_t opt)
1441 {
1442 	int		rval;
1443 	uint16_t	flags;
1444 	ql_mbx_data_t	mr;
1445 	mbx_cmd_t	mc = {0};
1446 	mbx_cmd_t	*mcp = &mc;
1447 
1448 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1449 	    ha->instance, tq->d_id.b24, loop_id);
1450 
1451 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1452 		flags = CF_CMD_PLOGI;
1453 		if ((opt & LLF_PLOGI) == 0) {
1454 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1455 		}
1456 		rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1457 	} else {
1458 		mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1459 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1460 			mcp->mb[1] = loop_id;
1461 		} else {
1462 			mcp->mb[1] = (uint16_t)(loop_id << 8);
1463 		}
1464 		mcp->mb[2] = opt;
1465 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1466 		mcp->in_mb = MBX_0;
1467 		mcp->timeout = MAILBOX_TOV;
1468 		rval = ql_mailbox_command(ha, mcp);
1469 	}
1470 
1471 	if (rval != QL_SUCCESS) {
1472 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1473 		    loop_id, rval);
1474 	} else {
1475 		/*EMPTY*/
1476 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1477 	}
1478 
1479 	return (rval);
1480 }
1481 
1482 /*
1483  * ql_login_fport
1484  *	Issue login fabric port mailbox command.
1485  *
1486  * Input:
1487  *	ha:		adapter state pointer.
1488  *	tq:		target queue pointer.
1489  *	loop_id:	FC loop id.
1490  *	opt:		options.
1491  *			LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1492  *	mr:		pointer for mailbox data.
1493  *
1494  * Returns:
1495  *	ql local function return status code.
1496  *
1497  * Context:
1498  *	Kernel context.
1499  */
1500 int
ql_login_fport(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t opt,ql_mbx_data_t * mr)1501 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1502     uint16_t opt, ql_mbx_data_t *mr)
1503 {
1504 	int		rval;
1505 	uint16_t	flags;
1506 	mbx_cmd_t	mc = {0};
1507 	mbx_cmd_t	*mcp = &mc;
1508 
1509 	QL_PRINT_3(CE_CONT, "(%d): started, d_id=%xh, loop_id=%xh\n",
1510 	    ha->instance, tq->d_id.b24, loop_id);
1511 
1512 	if ((tq->d_id.b24 & 0xffffff) == 0xfffffa) {
1513 		opt = (uint16_t)(opt | LFF_NO_PRLI);
1514 	}
1515 
1516 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1517 		flags = CF_CMD_PLOGI;
1518 		if (opt & LFF_NO_PLOGI) {
1519 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1520 		}
1521 		if (opt & LFF_NO_PRLI) {
1522 			flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1523 		}
1524 		rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1525 	} else {
1526 		mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1527 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1528 			mcp->mb[1] = loop_id;
1529 			mcp->mb[10] = opt;
1530 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1531 		} else {
1532 			mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1533 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1534 		}
1535 		mcp->mb[2] = MSW(tq->d_id.b24);
1536 		mcp->mb[3] = LSW(tq->d_id.b24);
1537 		mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1538 		mcp->timeout = MAILBOX_TOV;
1539 		rval = ql_mailbox_command(ha, mcp);
1540 
1541 		/* Return mailbox data. */
1542 		if (mr != NULL) {
1543 			mr->mb[0] = mcp->mb[0];
1544 			mr->mb[1] = mcp->mb[1];
1545 			mr->mb[2] = mcp->mb[2];
1546 			mr->mb[6] = mcp->mb[6];
1547 			mr->mb[7] = mcp->mb[7];
1548 		}
1549 	}
1550 
1551 	if (rval != QL_SUCCESS) {
1552 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1553 		    "mb2=%04x\n", tq->d_id.b24, loop_id, rval, mr->mb[1],
1554 		    mr->mb[2]);
1555 	} else {
1556 		/*EMPTY*/
1557 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1558 	}
1559 
1560 	return (rval);
1561 }
1562 
1563 /*
1564  * ql_logout_fabric_port
1565  *	Issue logout fabric port mailbox command.
1566  *
1567  * Input:
1568  *	ha:	adapter state pointer.
1569  *	tq:	target queue pointer.
1570  *
1571  * Returns:
1572  *	ql local function return status code.
1573  *
1574  * Context:
1575  *	Kernel context.
1576  */
1577 int
ql_logout_fabric_port(ql_adapter_state_t * ha,ql_tgt_t * tq)1578 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1579 {
1580 	int		rval;
1581 	uint16_t	flag;
1582 	ql_mbx_data_t	mr;
1583 	mbx_cmd_t	mc = {0};
1584 	mbx_cmd_t	*mcp = &mc;
1585 
1586 	QL_PRINT_3(CE_CONT, "(%d): started, loop_id=%xh d_id=%xh\n",
1587 	    ha->instance, tq->loop_id, tq->d_id.b24);
1588 
1589 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1590 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1591 		    CFO_EXPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE :
1592 		    CFO_IMPLICIT_LOGO |CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1593 		rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1594 	} else {
1595 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?  1 : 0);
1596 		mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1597 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1598 			mcp->mb[1] = tq->loop_id;
1599 			mcp->mb[10] = flag;
1600 			mcp->out_mb = MBX_10|MBX_1|MBX_0;
1601 		} else {
1602 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1603 			mcp->out_mb = MBX_1|MBX_0;
1604 		}
1605 		mcp->in_mb = MBX_0;
1606 		mcp->timeout = MAILBOX_TOV;
1607 		rval = ql_mailbox_command(ha, mcp);
1608 	}
1609 
1610 	if (rval != QL_SUCCESS) {
1611 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", rval,
1612 		    tq->d_id.b24, tq->loop_id);
1613 	} else {
1614 		/*EMPTY*/
1615 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1616 	}
1617 
1618 	return (rval);
1619 }
1620 
1621 /*
1622  * ql_log_iocb
1623  *	Function issues login/logout IOCB.
1624  *
1625  * Input:
1626  *	ha:		adapter state pointer.
1627  *	tq:		target queue pointer.
1628  *	loop_id:	FC Loop ID.
1629  *	flags:		control flags.
1630  *	mr:		pointer for mailbox data.
1631  *
1632  * Returns:
1633  *	ql local function return status code.
1634  *
1635  * Context:
1636  *	Kernel context.
1637  */
1638 int
ql_log_iocb(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t flags,ql_mbx_data_t * mr)1639 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1640     uint16_t flags, ql_mbx_data_t *mr)
1641 {
1642 	ql_mbx_iocb_t	*pkt;
1643 	int		rval;
1644 	uint32_t	pkt_size;
1645 
1646 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1647 
1648 	pkt_size = sizeof (ql_mbx_iocb_t);
1649 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1650 	if (pkt == NULL) {
1651 		EL(ha, "failed, kmem_zalloc\n");
1652 		return (QL_MEMORY_ALLOC_FAILED);
1653 	}
1654 
1655 	pkt->log.entry_type = LOG_TYPE;
1656 	pkt->log.entry_count = 1;
1657 	pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1658 	pkt->log.control_flags = (uint16_t)LE_16(flags);
1659 	pkt->log.port_id[0] = tq->d_id.b.al_pa;
1660 	pkt->log.port_id[1] = tq->d_id.b.area;
1661 	pkt->log.port_id[2] = tq->d_id.b.domain;
1662 	pkt->log.vp_index = ha->vp_index;
1663 
1664 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1665 	if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1666 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1667 		    pkt->log.entry_status, tq->d_id.b24);
1668 		rval = QL_FUNCTION_PARAMETER_ERROR;
1669 	}
1670 
1671 	if (rval == QL_SUCCESS) {
1672 		if (pkt->log.rsp_size == 0xB) {
1673 			LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1674 			tq->cmn_features = MSW(pkt->log.io_param[5]);
1675 			LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1676 			tq->conc_sequences = MSW(pkt->log.io_param[6]);
1677 			tq->relative_offset = LSW(pkt->log.io_param[6]);
1678 			LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1679 			tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1680 			tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1681 			LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1682 			tq->class3_open_sequences_per_exch =
1683 			    MSW(pkt->log.io_param[10]);
1684 			tq->prli_payload_length = 0x14;
1685 		}
1686 		if (mr != NULL) {
1687 			LITTLE_ENDIAN_16(&pkt->log.status);
1688 			LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1689 			LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1690 
1691 			if (pkt->log.status != CS_COMPLETE) {
1692 				EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1693 				    "%xh\n", pkt->log.status,
1694 				    pkt->log.io_param[0],
1695 				    pkt->log.io_param[1]);
1696 
1697 				switch (pkt->log.io_param[0]) {
1698 				case CS0_NO_LINK:
1699 				case CS0_FIRMWARE_NOT_READY:
1700 					mr->mb[0] = MBS_COMMAND_ERROR;
1701 					mr->mb[1] = 1;
1702 					break;
1703 				case CS0_NO_IOCB:
1704 				case CS0_NO_PCB_ALLOCATED:
1705 					mr->mb[0] = MBS_COMMAND_ERROR;
1706 					mr->mb[1] = 2;
1707 					break;
1708 				case CS0_NO_EXCH_CTRL_BLK:
1709 					mr->mb[0] = MBS_COMMAND_ERROR;
1710 					mr->mb[1] = 3;
1711 					break;
1712 				case CS0_COMMAND_FAILED:
1713 					mr->mb[0] = MBS_COMMAND_ERROR;
1714 					mr->mb[1] = 4;
1715 					switch (LSB(pkt->log.io_param[1])) {
1716 					case CS1_PLOGI_RESPONSE_FAILED:
1717 						mr->mb[2] = 3;
1718 						break;
1719 					case CS1_PRLI_FAILED:
1720 						mr->mb[2] = 4;
1721 						break;
1722 					case CS1_PRLI_RESPONSE_FAILED:
1723 						mr->mb[2] = 5;
1724 						break;
1725 					case CS1_COMMAND_LOGGED_OUT:
1726 						mr->mb[2] = 7;
1727 						break;
1728 					case CS1_PLOGI_FAILED:
1729 					default:
1730 						EL(ha, "log iop1 = %xh\n",
1731 						    LSB(pkt->log.io_param[1]))
1732 						mr->mb[2] = 2;
1733 						break;
1734 					}
1735 					break;
1736 				case CS0_PORT_NOT_LOGGED_IN:
1737 					mr->mb[0] = MBS_COMMAND_ERROR;
1738 					mr->mb[1] = 4;
1739 					mr->mb[2] = 7;
1740 					break;
1741 				case CS0_NO_FLOGI_ACC:
1742 				case CS0_NO_FABRIC_PRESENT:
1743 					mr->mb[0] = MBS_COMMAND_ERROR;
1744 					mr->mb[1] = 5;
1745 					break;
1746 				case CS0_ELS_REJECT_RECEIVED:
1747 					mr->mb[0] = MBS_COMMAND_ERROR;
1748 					mr->mb[1] = 0xd;
1749 					break;
1750 				case CS0_PORT_ID_USED:
1751 					mr->mb[0] = MBS_PORT_ID_USED;
1752 					mr->mb[1] = LSW(pkt->log.io_param[1]);
1753 					break;
1754 				case CS0_N_PORT_HANDLE_USED:
1755 					mr->mb[0] = MBS_LOOP_ID_USED;
1756 					mr->mb[1] = MSW(pkt->log.io_param[1]);
1757 					mr->mb[2] = LSW(pkt->log.io_param[1]);
1758 					break;
1759 				case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1760 					mr->mb[0] = MBS_ALL_IDS_IN_USE;
1761 					break;
1762 				case CS0_CMD_PARAMETER_ERROR:
1763 				default:
1764 					EL(ha, "pkt->log iop[0]=%xh\n",
1765 					    pkt->log.io_param[0]);
1766 					mr->mb[0] =
1767 					    MBS_COMMAND_PARAMETER_ERROR;
1768 					break;
1769 				}
1770 			} else {
1771 				QL_PRINT_3(CE_CONT, "(%d): status=%xh\n",
1772 				    ha->instance, pkt->log.status);
1773 
1774 				mr->mb[0] = MBS_COMMAND_COMPLETE;
1775 				mr->mb[1] = (uint16_t)
1776 				    (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1777 				if (pkt->log.io_param[0] & BIT_8) {
1778 					mr->mb[1] = (uint16_t)
1779 					    (mr->mb[1] | BIT_1);
1780 				}
1781 			}
1782 			rval = mr->mb[0];
1783 		}
1784 
1785 	}
1786 
1787 	kmem_free(pkt, pkt_size);
1788 
1789 	if (rval != QL_SUCCESS) {
1790 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1791 	} else {
1792 		/*EMPTY*/
1793 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1794 	}
1795 
1796 	return (rval);
1797 }
1798 
1799 /*
1800  * ql_get_port_database
1801  *	Issue get port database mailbox command
1802  *	and copy context to device queue.
1803  *
1804  * Input:
1805  *	ha:	adapter state pointer.
1806  *	tq:	target queue pointer.
1807  *	opt:	options.
1808  *		PDF_NONE, PDF_PLOGI, PDF_ADISC
1809  * Returns:
1810  *	ql local function return status code.
1811  *
1812  * Context:
1813  *	Kernel context.
1814  */
1815 int
ql_get_port_database(ql_adapter_state_t * ha,ql_tgt_t * tq,uint8_t opt)1816 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1817 {
1818 	int			rval;
1819 	dma_mem_t		mem_desc;
1820 	mbx_cmd_t		mc = {0};
1821 	mbx_cmd_t		*mcp = &mc;
1822 	port_database_23_t	*pd23;
1823 
1824 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1825 
1826 	pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1827 	if (pd23 == NULL) {
1828 		rval = QL_MEMORY_ALLOC_FAILED;
1829 		EL(ha, "failed, rval = %xh\n", rval);
1830 		return (rval);
1831 	}
1832 
1833 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1834 	    PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1835 		return (QL_MEMORY_ALLOC_FAILED);
1836 	}
1837 
1838 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
1839 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1840 		mcp->mb[1] = tq->loop_id;
1841 		mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1842 		mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1843 		mcp->mb[9] = ha->vp_index;
1844 		mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1845 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1846 		    MBX_2|MBX_1|MBX_0;
1847 	} else {
1848 		mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1849 		    MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1850 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1851 			mcp->mb[1] = tq->loop_id;
1852 			mcp->mb[10] = opt;
1853 			mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1854 			    MBX_2|MBX_1|MBX_0;
1855 		} else {
1856 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1857 			mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1858 		}
1859 	}
1860 
1861 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1862 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1863 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1864 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1865 	mcp->in_mb = MBX_0;
1866 	mcp->timeout = MAILBOX_TOV;
1867 	rval = ql_mailbox_command(ha, mcp);
1868 
1869 	if (rval == QL_SUCCESS) {
1870 		ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1871 	}
1872 
1873 	ql_free_dma_resource(ha, &mem_desc);
1874 
1875 	if (rval == QL_SUCCESS) {
1876 		if (CFG_IST(ha, CFG_CTRL_24258081)) {
1877 			port_database_24_t *pd24 = (port_database_24_t *)pd23;
1878 
1879 			tq->master_state = pd24->current_login_state;
1880 			tq->slave_state = pd24->last_stable_login_state;
1881 			if (PD_PORT_LOGIN(tq)) {
1882 				/* Names are big endian. */
1883 				bcopy((void *)&pd24->port_name[0],
1884 				    (void *)&tq->port_name[0], 8);
1885 				bcopy((void *)&pd24->node_name[0],
1886 				    (void *)&tq->node_name[0], 8);
1887 				tq->hard_addr.b.al_pa = pd24->hard_address[2];
1888 				tq->hard_addr.b.area = pd24->hard_address[1];
1889 				tq->hard_addr.b.domain = pd24->hard_address[0];
1890 				tq->class3_rcv_data_size =
1891 				    pd24->receive_data_size;
1892 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1893 				tq->prli_svc_param_word_0 =
1894 				    pd24->PRLI_service_parameter_word_0;
1895 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1896 				tq->prli_svc_param_word_3 =
1897 				    pd24->PRLI_service_parameter_word_3;
1898 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1899 			}
1900 		} else {
1901 			tq->master_state = pd23->master_state;
1902 			tq->slave_state = pd23->slave_state;
1903 			if (PD_PORT_LOGIN(tq)) {
1904 				/* Names are big endian. */
1905 				bcopy((void *)&pd23->port_name[0],
1906 				    (void *)&tq->port_name[0], 8);
1907 				bcopy((void *)&pd23->node_name[0],
1908 				    (void *)&tq->node_name[0], 8);
1909 				tq->hard_addr.b.al_pa = pd23->hard_address[2];
1910 				tq->hard_addr.b.area = pd23->hard_address[1];
1911 				tq->hard_addr.b.domain = pd23->hard_address[0];
1912 				tq->cmn_features = pd23->common_features;
1913 				LITTLE_ENDIAN_16(&tq->cmn_features);
1914 				tq->conc_sequences =
1915 				    pd23->total_concurrent_sequences;
1916 				LITTLE_ENDIAN_16(&tq->conc_sequences);
1917 				tq->relative_offset =
1918 				    pd23->RO_by_information_category;
1919 				LITTLE_ENDIAN_16(&tq->relative_offset);
1920 				tq->class3_recipient_ctl = pd23->recipient;
1921 				LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
1922 				tq->class3_rcv_data_size =
1923 				    pd23->receive_data_size;
1924 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1925 				tq->class3_conc_sequences =
1926 				    pd23->concurrent_sequences;
1927 				LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
1928 				tq->class3_open_sequences_per_exch =
1929 				    pd23->open_sequences_per_exchange;
1930 				LITTLE_ENDIAN_16(
1931 				    &tq->class3_open_sequences_per_exch);
1932 				tq->prli_payload_length =
1933 				    pd23->PRLI_payload_length;
1934 				LITTLE_ENDIAN_16(&tq->prli_payload_length);
1935 				tq->prli_svc_param_word_0 =
1936 				    pd23->PRLI_service_parameter_word_0;
1937 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1938 				tq->prli_svc_param_word_3 =
1939 				    pd23->PRLI_service_parameter_word_3;
1940 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1941 			}
1942 		}
1943 
1944 		if (!PD_PORT_LOGIN(tq)) {
1945 			EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
1946 			    "master=%xh, slave=%xh\n", tq->d_id.b24,
1947 			    tq->loop_id, tq->master_state, tq->slave_state);
1948 			rval = QL_NOT_LOGGED_IN;
1949 		} else {
1950 			tq->flags = tq->prli_svc_param_word_3 &
1951 			    PRLI_W3_TARGET_FUNCTION ?
1952 			    tq->flags & ~TQF_INITIATOR_DEVICE :
1953 			    tq->flags | TQF_INITIATOR_DEVICE;
1954 
1955 			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
1956 				tq->flags = tq->prli_svc_param_word_3 &
1957 				    PRLI_W3_RETRY ?
1958 				    tq->flags | TQF_TAPE_DEVICE :
1959 				    tq->flags & ~TQF_TAPE_DEVICE;
1960 			} else {
1961 				tq->flags &= ~TQF_TAPE_DEVICE;
1962 			}
1963 		}
1964 	}
1965 
1966 	kmem_free(pd23, PORT_DATABASE_SIZE);
1967 
1968 	if ((rval != QL_SUCCESS) && (rval != QL_PARAMETER_ERROR)) {
1969 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1970 		    tq->loop_id, rval);
1971 	} else {
1972 		/*EMPTY*/
1973 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1974 	}
1975 
1976 	return (rval);
1977 }
1978 
1979 /*
1980  * ql_get_loop_position_map
1981  *	Issue get loop position map mailbox command.
1982  *
1983  * Input:
1984  *	ha:	adapter state pointer.
1985  *	size:	size of data buffer.
1986  *	bufp:	data pointer for DMA data.
1987  *
1988  * Returns:
1989  *	ql local function return status code.
1990  *
1991  * Context:
1992  *	Kernel context.
1993  */
1994 int
ql_get_loop_position_map(ql_adapter_state_t * ha,size_t size,caddr_t bufp)1995 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
1996 {
1997 	int		rval;
1998 	dma_mem_t	mem_desc;
1999 	mbx_cmd_t	mc = {0};
2000 	mbx_cmd_t	*mcp = &mc;
2001 
2002 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2003 
2004 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2005 	    (uint32_t)size)) != QL_SUCCESS) {
2006 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2007 		return (QL_MEMORY_ALLOC_FAILED);
2008 	}
2009 
2010 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2011 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2012 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2013 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2014 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2015 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2016 	mcp->in_mb = MBX_1|MBX_0;
2017 	mcp->timeout = MAILBOX_TOV;
2018 	rval = ql_mailbox_command(ha, mcp);
2019 
2020 	if (rval == QL_SUCCESS) {
2021 		ql_get_mbox_dma_data(&mem_desc, bufp);
2022 	}
2023 
2024 	ql_free_dma_resource(ha, &mem_desc);
2025 
2026 	if (rval != QL_SUCCESS) {
2027 		EL(ha, "failed=%xh\n", rval);
2028 	} else {
2029 		/*EMPTY*/
2030 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2031 	}
2032 
2033 	return (rval);
2034 }
2035 
2036 /*
2037  * ql_set_rnid_params
2038  *	Issue set RNID parameters mailbox command.
2039  *
2040  * Input:
2041  *	ha:		adapter state pointer.
2042  *	size:		size of data buffer.
2043  *	bufp:		data pointer for DMA data.
2044  *
2045  * Returns:
2046  *	ql local function return status code.
2047  *
2048  * Context:
2049  *	Kernel context.
2050  */
2051 int
ql_set_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2052 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2053 {
2054 	int		rval;
2055 	dma_mem_t	mem_desc;
2056 	mbx_cmd_t	mc = {0};
2057 	mbx_cmd_t	*mcp = &mc;
2058 
2059 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2060 
2061 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2062 	    (uint32_t)size)) != QL_SUCCESS) {
2063 		EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2064 		return (rval);
2065 	}
2066 
2067 	mcp->mb[0] = MBC_SET_PARAMETERS;
2068 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2069 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2070 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2071 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2072 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2073 	mcp->in_mb = MBX_0;
2074 	mcp->timeout = MAILBOX_TOV;
2075 	rval = ql_mailbox_command(ha, mcp);
2076 
2077 	ql_free_dma_resource(ha, &mem_desc);
2078 
2079 	if (rval != QL_SUCCESS) {
2080 		EL(ha, "failed, rval = %xh\n", rval);
2081 	} else {
2082 		/*EMPTY*/
2083 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2084 	}
2085 
2086 	return (rval);
2087 }
2088 
2089 /*
2090  * ql_send_rnid_els
2091  *	Issue a send node identfication data mailbox command.
2092  *
2093  * Input:
2094  *	ha:		adapter state pointer.
2095  *	loop_id:	FC loop id.
2096  *	opt:		options.
2097  *	size:		size of data buffer.
2098  *	bufp:		data pointer for DMA data.
2099  *
2100  * Returns:
2101  *	ql local function return status code.
2102  *
2103  * Context:
2104  *	Kernel context.
2105  */
2106 int
ql_send_rnid_els(ql_adapter_state_t * ha,uint16_t loop_id,uint8_t opt,size_t size,caddr_t bufp)2107 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2108     size_t size, caddr_t bufp)
2109 {
2110 	int		rval;
2111 	dma_mem_t	mem_desc;
2112 	mbx_cmd_t	mc = {0};
2113 	mbx_cmd_t	*mcp = &mc;
2114 
2115 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2116 
2117 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2118 	    (uint32_t)size)) != QL_SUCCESS) {
2119 		return (QL_MEMORY_ALLOC_FAILED);
2120 	}
2121 
2122 	mcp->mb[0] = MBC_SEND_RNID_ELS;
2123 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2124 		mcp->mb[1] = loop_id;
2125 		mcp->mb[9] = ha->vp_index;
2126 		mcp->mb[10] = opt;
2127 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2128 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2129 		mcp->mb[1] = loop_id;
2130 		mcp->mb[10] = opt;
2131 		mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2132 	} else {
2133 		mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2134 		mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2135 	}
2136 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2137 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2138 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2139 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2140 	mcp->in_mb = MBX_0;
2141 	mcp->timeout = MAILBOX_TOV;
2142 	rval = ql_mailbox_command(ha, mcp);
2143 
2144 	if (rval == QL_SUCCESS) {
2145 		ql_get_mbox_dma_data(&mem_desc, bufp);
2146 	}
2147 
2148 	ql_free_dma_resource(ha, &mem_desc);
2149 
2150 	if (rval != QL_SUCCESS) {
2151 		EL(ha, "failed, rval = %xh\n", rval);
2152 	} else {
2153 		/*EMPTY*/
2154 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2155 	}
2156 
2157 	return (rval);
2158 }
2159 
2160 /*
2161  * ql_get_rnid_params
2162  *	Issue get RNID parameters mailbox command.
2163  *
2164  * Input:
2165  *	ha:	adapter state pointer.
2166  *	size:	size of data buffer.
2167  *	bufp:	data pointer for DMA data.
2168  *
2169  * Returns:
2170  *	ql local function return status code.
2171  *
2172  * Context:
2173  *	Kernel context.
2174  */
2175 int
ql_get_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2176 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2177 {
2178 	int		rval;
2179 	dma_mem_t	mem_desc;
2180 	mbx_cmd_t	mc = {0};
2181 	mbx_cmd_t	*mcp = &mc;
2182 
2183 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2184 
2185 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2186 	    (uint32_t)size)) != QL_SUCCESS) {
2187 		return (QL_MEMORY_ALLOC_FAILED);
2188 	}
2189 
2190 	mcp->mb[0] = MBC_GET_PARAMETERS;
2191 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2192 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2193 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2194 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2195 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2196 	mcp->in_mb = MBX_0;
2197 	mcp->timeout = MAILBOX_TOV;
2198 	rval = ql_mailbox_command(ha, mcp);
2199 
2200 	if (rval == QL_SUCCESS) {
2201 		ql_get_mbox_dma_data(&mem_desc, bufp);
2202 	}
2203 
2204 	ql_free_dma_resource(ha, &mem_desc);
2205 
2206 	if (rval != QL_SUCCESS) {
2207 		EL(ha, "failed=%xh\n", rval);
2208 	} else {
2209 		/*EMPTY*/
2210 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2211 	}
2212 
2213 	return (rval);
2214 }
2215 
2216 /*
2217  * ql_get_link_status
2218  *	Issue get link status mailbox command.
2219  *
2220  * Input:
2221  *	ha:		adapter state pointer.
2222  *	loop_id:	FC loop id or n_port_hdl.
2223  *	size:		size of data buffer.
2224  *	bufp:		data pointer for DMA data.
2225  *	port_no:	port number to query.
2226  *
2227  * Returns:
2228  *	ql local function return status code.
2229  *
2230  * Context:
2231  *	Kernel context.
2232  */
2233 int
ql_get_link_status(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2234 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2235     caddr_t bufp, uint8_t port_no)
2236 {
2237 	dma_mem_t	mem_desc;
2238 	mbx_cmd_t	mc = {0};
2239 	mbx_cmd_t	*mcp = &mc;
2240 	int		rval = QL_SUCCESS;
2241 	int		retry = 0;
2242 
2243 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2244 
2245 	do {
2246 		if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2247 		    (uint32_t)size)) != QL_SUCCESS) {
2248 			EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2249 			return (QL_MEMORY_ALLOC_FAILED);
2250 		}
2251 
2252 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2253 		if (CFG_IST(ha, CFG_CTRL_24258081)) {
2254 			if (loop_id == ha->loop_id) {
2255 				mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2256 				mcp->mb[8] = (uint16_t)(size >> 2);
2257 				mcp->out_mb = MBX_10|MBX_8;
2258 			} else {
2259 				mcp->mb[1] = loop_id;
2260 				mcp->mb[4] = port_no;
2261 				mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2262 				mcp->out_mb = MBX_10|MBX_4;
2263 			}
2264 		} else {
2265 			if (retry) {
2266 				port_no = (uint8_t)(port_no | BIT_3);
2267 			}
2268 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2269 				mcp->mb[1] = loop_id;
2270 				mcp->mb[10] = port_no;
2271 				mcp->out_mb = MBX_10;
2272 			} else {
2273 				mcp->mb[1] = (uint16_t)((loop_id << 8) |
2274 				    port_no);
2275 				mcp->out_mb = 0;
2276 			}
2277 		}
2278 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2279 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2280 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2281 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2282 		mcp->in_mb = MBX_1|MBX_0;
2283 		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2284 		mcp->timeout = MAILBOX_TOV;
2285 
2286 		rval = ql_mailbox_command(ha, mcp);
2287 
2288 		if (rval == QL_SUCCESS) {
2289 			ql_get_mbox_dma_data(&mem_desc, bufp);
2290 		}
2291 
2292 		ql_free_dma_resource(ha, &mem_desc);
2293 
2294 		if (rval != QL_SUCCESS) {
2295 			EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2296 		}
2297 
2298 		/*
2299 		 * Some of the devices want d_id in the payload,
2300 		 * strictly as per standard. Let's retry.
2301 		 */
2302 
2303 	} while (rval == QL_COMMAND_ERROR && !retry++);
2304 
2305 	if (rval != QL_SUCCESS) {
2306 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2307 	} else {
2308 		/*EMPTY*/
2309 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2310 	}
2311 
2312 	return (rval);
2313 }
2314 
2315 /*
2316  * ql_get_status_counts
2317  *	Issue get adapter link status counts mailbox command.
2318  *
2319  * Input:
2320  *	ha:		adapter state pointer.
2321  *	loop_id:	FC loop id or n_port_hdl.
2322  *	size:		size of data buffer.
2323  *	bufp:		data pointer for DMA data.
2324  *	port_no:	port number to query.
2325  *
2326  * Returns:
2327  *	ql local function return status code.
2328  *
2329  * Context:
2330  *	Kernel context.
2331  */
2332 int
ql_get_status_counts(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2333 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2334     caddr_t bufp, uint8_t port_no)
2335 {
2336 	dma_mem_t	mem_desc;
2337 	mbx_cmd_t	mc = {0};
2338 	mbx_cmd_t	*mcp = &mc;
2339 	int		rval = QL_SUCCESS;
2340 
2341 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2342 
2343 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2344 	    (uint32_t)size)) != QL_SUCCESS) {
2345 		EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2346 		return (QL_MEMORY_ALLOC_FAILED);
2347 	}
2348 
2349 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2350 		mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2351 		mcp->mb[8] = (uint16_t)(size / 4);
2352 		mcp->out_mb = MBX_10|MBX_8;
2353 	} else {
2354 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2355 
2356 		/* allows reporting when link is down */
2357 		if (CFG_IST(ha, CFG_CTRL_2200) == 0) {
2358 			port_no = (uint8_t)(port_no | BIT_6);
2359 		}
2360 
2361 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2362 			mcp->mb[1] = loop_id;
2363 			mcp->mb[10] = port_no;
2364 			mcp->out_mb = MBX_10|MBX_1;
2365 		} else {
2366 			mcp->mb[1] = (uint16_t)((loop_id << 8) |
2367 			    port_no);
2368 			mcp->out_mb = MBX_1;
2369 		}
2370 	}
2371 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2372 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2373 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2374 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2375 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2376 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2377 	mcp->timeout = MAILBOX_TOV;
2378 	rval = ql_mailbox_command(ha, mcp);
2379 
2380 	if (rval == QL_SUCCESS) {
2381 		ql_get_mbox_dma_data(&mem_desc, bufp);
2382 	}
2383 
2384 	ql_free_dma_resource(ha, &mem_desc);
2385 
2386 	if (rval != QL_SUCCESS) {
2387 		EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2388 		    mcp->mb[1], mcp->mb[2]);
2389 	} else {
2390 		/*EMPTY*/
2391 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2392 	}
2393 
2394 	return (rval);
2395 }
2396 
2397 /*
2398  * ql_reset_link_status
2399  *	Issue Reset Link Error Status mailbox command
2400  *
2401  * Input:
2402  *	ha:	adapter state pointer.
2403  *
2404  * Returns:
2405  *	ql local function return status code.
2406  *
2407  * Context:
2408  *	Kernel context.
2409  */
2410 int
ql_reset_link_status(ql_adapter_state_t * ha)2411 ql_reset_link_status(ql_adapter_state_t *ha)
2412 {
2413 	int		rval;
2414 	mbx_cmd_t	mc = {0};
2415 	mbx_cmd_t	*mcp = &mc;
2416 
2417 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2418 
2419 	mcp->mb[0] = MBC_RESET_LINK_STATUS;
2420 	mcp->out_mb = MBX_0;
2421 	mcp->in_mb = MBX_0;
2422 	mcp->timeout = MAILBOX_TOV;
2423 	rval = ql_mailbox_command(ha, mcp);
2424 
2425 	if (rval != QL_SUCCESS) {
2426 		EL(ha, "failed=%xh\n", rval);
2427 	} else {
2428 		/*EMPTY*/
2429 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2430 	}
2431 
2432 	return (rval);
2433 }
2434 
2435 /*
2436  * ql_loop_reset
2437  *	Issue loop reset.
2438  *
2439  * Input:
2440  *	ha:	adapter state pointer.
2441  *
2442  * Returns:
2443  *	ql local function return status code.
2444  *
2445  * Context:
2446  *	Kernel context.
2447  */
2448 int
ql_loop_reset(ql_adapter_state_t * ha)2449 ql_loop_reset(ql_adapter_state_t *ha)
2450 {
2451 	int	rval;
2452 
2453 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2454 
2455 	if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2456 		rval = ql_lip_reset(ha, 0xff);
2457 	} else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2458 		rval = ql_full_login_lip(ha);
2459 	} else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2460 		rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2461 	} else {
2462 		rval = ql_initiate_lip(ha);
2463 	}
2464 
2465 	if (rval != QL_SUCCESS) {
2466 		EL(ha, "failed, rval = %xh\n", rval);
2467 	} else {
2468 		/*EMPTY*/
2469 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2470 	}
2471 
2472 	return (rval);
2473 }
2474 
2475 /*
2476  * ql_initiate_lip
2477  *	Initiate LIP mailbox command.
2478  *
2479  * Input:
2480  *	ha:	adapter state pointer.
2481  *
2482  * Returns:
2483  *	ql local function return status code.
2484  *
2485  * Context:
2486  *	Kernel context.
2487  */
2488 int
ql_initiate_lip(ql_adapter_state_t * ha)2489 ql_initiate_lip(ql_adapter_state_t *ha)
2490 {
2491 	int		rval;
2492 	mbx_cmd_t	mc = {0};
2493 	mbx_cmd_t	*mcp = &mc;
2494 
2495 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2496 
2497 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2498 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2499 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2500 		    BIT_1 : BIT_4);
2501 		mcp->mb[3] = ha->loop_reset_delay;
2502 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2503 	} else {
2504 		mcp->mb[0] = MBC_INITIATE_LIP;
2505 		mcp->out_mb = MBX_0;
2506 	}
2507 	mcp->in_mb = MBX_0;
2508 	mcp->timeout = MAILBOX_TOV;
2509 	rval = ql_mailbox_command(ha, mcp);
2510 
2511 	if (rval != QL_SUCCESS) {
2512 		EL(ha, "failed, rval = %xh\n", rval);
2513 	} else {
2514 		/*EMPTY*/
2515 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2516 	}
2517 
2518 	return (rval);
2519 }
2520 
2521 /*
2522  * ql_full_login_lip
2523  *	Issue full login LIP mailbox command.
2524  *
2525  * Input:
2526  *	ha:	adapter state pointer.
2527  *
2528  * Returns:
2529  *	ql local function return status code.
2530  *
2531  * Context:
2532  *	Kernel context.
2533  */
2534 int
ql_full_login_lip(ql_adapter_state_t * ha)2535 ql_full_login_lip(ql_adapter_state_t *ha)
2536 {
2537 	int		rval;
2538 	mbx_cmd_t	mc = {0};
2539 	mbx_cmd_t	*mcp = &mc;
2540 
2541 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2542 
2543 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2544 	if (CFG_IST(ha, CFG_CTRL_2425)) {
2545 		mcp->mb[1] = BIT_3;
2546 	} else if (CFG_IST(ha, CFG_CTRL_8081)) {
2547 		mcp->mb[1] = BIT_1;
2548 	}
2549 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2550 	mcp->in_mb = MBX_0;
2551 	mcp->timeout = MAILBOX_TOV;
2552 	rval = ql_mailbox_command(ha, mcp);
2553 
2554 	if (rval != QL_SUCCESS) {
2555 		EL(ha, "failed, rval = %xh\n", rval);
2556 	} else {
2557 		/*EMPTY*/
2558 		QL_PRINT_3(CE_CONT, "(%d): done", ha->instance);
2559 	}
2560 
2561 	return (rval);
2562 }
2563 
2564 /*
2565  * ql_lip_reset
2566  *	Issue lip reset to a port.
2567  *
2568  * Input:
2569  *	ha:		adapter state pointer.
2570  *	loop_id:	FC loop id.
2571  *
2572  * Returns:
2573  *	ql local function return status code.
2574  *
2575  * Context:
2576  *	Kernel context.
2577  */
2578 int
ql_lip_reset(ql_adapter_state_t * ha,uint16_t loop_id)2579 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2580 {
2581 	int		rval;
2582 	mbx_cmd_t	mc = {0};
2583 	mbx_cmd_t	*mcp = &mc;
2584 
2585 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2586 
2587 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2588 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2589 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_8081) ?
2590 		    BIT_1 : BIT_6);
2591 		mcp->mb[3] = ha->loop_reset_delay;
2592 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2593 	} else {
2594 		mcp->mb[0] = MBC_LIP_RESET;
2595 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2596 			mcp->mb[1] = loop_id;
2597 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2598 		} else {
2599 			mcp->mb[1] = (uint16_t)(loop_id << 8);
2600 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2601 		}
2602 		mcp->mb[2] = ha->loop_reset_delay;
2603 	}
2604 	mcp->in_mb = MBX_0;
2605 	mcp->timeout = MAILBOX_TOV;
2606 	rval = ql_mailbox_command(ha, mcp);
2607 
2608 	if (rval != QL_SUCCESS) {
2609 		EL(ha, "failed, rval = %xh\n", rval);
2610 	} else {
2611 		/*EMPTY*/
2612 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2613 	}
2614 
2615 	return (rval);
2616 }
2617 
2618 /*
2619  * ql_abort_command
2620  *	Abort command aborts a specified IOCB.
2621  *
2622  * Input:
2623  *	ha:	adapter state pointer.
2624  *	sp:	SRB structure pointer.
2625  *
2626  * Returns:
2627  *	ql local function return status code.
2628  *
2629  * Context:
2630  *	Kernel context.
2631  */
2632 int
ql_abort_command(ql_adapter_state_t * ha,ql_srb_t * sp)2633 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2634 {
2635 	int		rval;
2636 	mbx_cmd_t	mc = {0};
2637 	mbx_cmd_t	*mcp = &mc;
2638 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2639 
2640 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2641 
2642 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2643 		rval = ql_abort_cmd_iocb(ha, sp);
2644 	} else {
2645 		mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2646 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2647 			mcp->mb[1] = tq->loop_id;
2648 		} else {
2649 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2650 		}
2651 		mcp->mb[2] = LSW(sp->handle);
2652 		mcp->mb[3] = MSW(sp->handle);
2653 		mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2654 		    sp->lun_queue->lun_no : 0);
2655 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2656 		mcp->in_mb = MBX_0;
2657 		mcp->timeout = MAILBOX_TOV;
2658 		rval = ql_mailbox_command(ha, mcp);
2659 	}
2660 
2661 	if (rval != QL_SUCCESS) {
2662 		EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2663 		    tq->d_id.b24, sp->handle);
2664 	} else {
2665 		/*EMPTY*/
2666 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2667 	}
2668 
2669 	return (rval);
2670 }
2671 
2672 /*
2673  * ql_abort_cmd_iocb
2674  *	Function issues abort command IOCB.
2675  *
2676  * Input:
2677  *	ha:	adapter state pointer.
2678  *	sp:	SRB structure pointer.
2679  *
2680  * Returns:
2681  *	ql local function return status code.
2682  *
2683  * Context:
2684  *	Interrupt or Kernel context, no mailbox commands allowed.
2685  */
2686 static int
ql_abort_cmd_iocb(ql_adapter_state_t * ha,ql_srb_t * sp)2687 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2688 {
2689 	ql_mbx_iocb_t	*pkt;
2690 	int		rval;
2691 	uint32_t	pkt_size;
2692 	uint16_t	comp_status;
2693 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2694 
2695 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2696 
2697 	pkt_size = sizeof (ql_mbx_iocb_t);
2698 	if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2699 		EL(ha, "failed, kmem_zalloc\n");
2700 		return (QL_MEMORY_ALLOC_FAILED);
2701 	}
2702 
2703 	pkt->abo.entry_type = ABORT_CMD_TYPE;
2704 	pkt->abo.entry_count = 1;
2705 	pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2706 	if (!CFG_IST(ha, CFG_CTRL_8021)) {
2707 		pkt->abo.options = AF_NO_ABTS;
2708 	}
2709 	pkt->abo.cmd_handle = LE_32(sp->handle);
2710 	pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2711 	pkt->abo.target_id[1] = tq->d_id.b.area;
2712 	pkt->abo.target_id[2] = tq->d_id.b.domain;
2713 	pkt->abo.vp_index = ha->vp_index;
2714 
2715 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2716 
2717 	if (rval == QL_SUCCESS) {
2718 		if ((pkt->abo.entry_status  & 0x3c) != 0) {
2719 			EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2720 			    pkt->abo.entry_status, tq->d_id.b24);
2721 			rval = QL_FUNCTION_PARAMETER_ERROR;
2722 		} else {
2723 			comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2724 			if (comp_status != CS_COMPLETE) {
2725 				EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2726 				    comp_status, tq->d_id.b24);
2727 				rval = QL_FUNCTION_FAILED;
2728 			}
2729 		}
2730 	}
2731 
2732 	kmem_free(pkt, pkt_size);
2733 
2734 	if (rval != QL_SUCCESS) {
2735 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2736 	} else {
2737 		/*EMPTY*/
2738 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2739 	}
2740 
2741 	return (rval);
2742 }
2743 
2744 /*
2745  * ql_verify_checksum
2746  *	Verify loaded RISC firmware.
2747  *
2748  * Input:
2749  *	ha = adapter state pointer.
2750  *
2751  * Returns:
2752  *	ql local function return status code.
2753  *
2754  * Context:
2755  *	Kernel context.
2756  */
2757 int
ql_verify_checksum(ql_adapter_state_t * ha)2758 ql_verify_checksum(ql_adapter_state_t *ha)
2759 {
2760 	int		rval;
2761 	mbx_cmd_t	mc = {0};
2762 	mbx_cmd_t	*mcp = &mc;
2763 
2764 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2765 
2766 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2767 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2768 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2769 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2770 	} else {
2771 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2772 	}
2773 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2774 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2775 	mcp->timeout = MAILBOX_TOV;
2776 	rval = ql_mailbox_command(ha, mcp);
2777 
2778 	if (rval != QL_SUCCESS) {
2779 		EL(ha, "failed, rval = %xh\n", rval);
2780 	} else {
2781 		/*EMPTY*/
2782 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2783 	}
2784 
2785 	return (rval);
2786 }
2787 
2788 /*
2789  * ql_get_id_list
2790  *	Get d_id and loop ID list.
2791  *
2792  * Input:
2793  *	ha:	adapter state pointer.
2794  *	bp:	data pointer for DMA data.
2795  *	size:	size of data buffer.
2796  *	mr:	pointer for mailbox data.
2797  *
2798  * Returns:
2799  *	ql local function return status code.
2800  *
2801  * Context:
2802  *	Kernel context.
2803  */
2804 int
ql_get_id_list(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,ql_mbx_data_t * mr)2805 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2806     ql_mbx_data_t *mr)
2807 {
2808 	int		rval;
2809 	dma_mem_t	mem_desc;
2810 	mbx_cmd_t	mc = {0};
2811 	mbx_cmd_t	*mcp = &mc;
2812 
2813 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2814 
2815 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2816 	    (uint32_t)size)) != QL_SUCCESS) {
2817 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2818 		return (QL_MEMORY_ALLOC_FAILED);
2819 	}
2820 
2821 	mcp->mb[0] = MBC_GET_ID_LIST;
2822 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
2823 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2824 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2825 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2826 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2827 		mcp->mb[8] = (uint16_t)size;
2828 		mcp->mb[9] = ha->vp_index;
2829 		mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2830 	} else {
2831 		mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2832 		mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2833 		mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2834 		mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2835 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2836 	}
2837 	mcp->in_mb = MBX_1|MBX_0;
2838 	mcp->timeout = MAILBOX_TOV;
2839 	rval = ql_mailbox_command(ha, mcp);
2840 
2841 	if (rval == QL_SUCCESS) {
2842 		ql_get_mbox_dma_data(&mem_desc, bp);
2843 	}
2844 
2845 	ql_free_dma_resource(ha, &mem_desc);
2846 
2847 	/* Return mailbox data. */
2848 	if (mr != NULL) {
2849 		mr->mb[0] = mcp->mb[0];
2850 		mr->mb[1] = mcp->mb[1];
2851 	}
2852 
2853 	if (rval != QL_SUCCESS) {
2854 		EL(ha, "failed, rval = %xh\n", rval);
2855 	} else {
2856 		/*EMPTY*/
2857 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2858 	}
2859 
2860 	return (rval);
2861 }
2862 
2863 /*
2864  * ql_wrt_risc_ram
2865  *	Load RISC RAM.
2866  *
2867  * Input:
2868  *	ha:		adapter state pointer.
2869  *	risc_address:	risc ram word address.
2870  *	bp:		DMA pointer.
2871  *	word_count:	16/32bit word count.
2872  *
2873  * Returns:
2874  *	ql local function return status code.
2875  *
2876  * Context:
2877  *	Kernel context.
2878  */
2879 int
ql_wrt_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)2880 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2881     uint32_t word_count)
2882 {
2883 	int		rval;
2884 	mbx_cmd_t	mc = {0};
2885 	mbx_cmd_t	*mcp = &mc;
2886 
2887 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2888 
2889 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2890 		mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
2891 		mcp->mb[4] = MSW(word_count);
2892 		mcp->mb[5] = LSW(word_count);
2893 		mcp->mb[6] = MSW(MSD(bp));
2894 		mcp->mb[7] = LSW(MSD(bp));
2895 		mcp->mb[8] = MSW(risc_address);
2896 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2897 		    MBX_0;
2898 	} else {
2899 		mcp->mb[0] = MBC_LOAD_RAM;
2900 		mcp->mb[4] = LSW(word_count);
2901 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2902 	}
2903 	mcp->mb[1] = LSW(risc_address);
2904 	mcp->mb[2] = MSW(LSD(bp));
2905 	mcp->mb[3] = LSW(LSD(bp));
2906 	mcp->in_mb = MBX_0;
2907 	mcp->timeout = MAILBOX_TOV;
2908 
2909 	rval = ql_mailbox_command(ha, mcp);
2910 
2911 	if (rval != QL_SUCCESS) {
2912 		EL(ha, "failed, rval = %xh\n", rval);
2913 	} else {
2914 		/*EMPTY*/
2915 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2916 	}
2917 
2918 	return (rval);
2919 }
2920 
2921 /*
2922  * ql_rd_risc_ram
2923  *	Get RISC RAM.
2924  *
2925  * Input:
2926  *	ha:		adapter state pointer.
2927  *	risc_address:	risc ram word address.
2928  *	bp:		direct data pointer.
2929  *	word_count:	16/32bit word count.
2930  *
2931  * Returns:
2932  *	ql local function return status code.
2933  *
2934  * Context:
2935  *	Kernel context.
2936  */
2937 int
ql_rd_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)2938 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2939     uint32_t word_count)
2940 {
2941 	int		rval;
2942 	mbx_cmd_t	mc = {0};
2943 	mbx_cmd_t	*mcp = &mc;
2944 
2945 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2946 
2947 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2948 		mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
2949 		mcp->mb[1] = LSW(risc_address);
2950 		mcp->mb[2] = MSW(LSD(bp));
2951 		mcp->mb[3] = LSW(LSD(bp));
2952 		mcp->mb[4] = MSW(word_count);
2953 		mcp->mb[5] = LSW(word_count);
2954 		mcp->mb[6] = MSW(MSD(bp));
2955 		mcp->mb[7] = LSW(MSD(bp));
2956 		mcp->mb[8] = MSW(risc_address);
2957 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
2958 		    MBX_0;
2959 	} else {
2960 		mcp->mb[0] = MBC_DUMP_RAM;	/* doesn't support 64bit addr */
2961 		mcp->mb[1] = LSW(risc_address);
2962 		mcp->mb[2] = MSW(LSD(bp));
2963 		mcp->mb[3] = LSW(LSD(bp));
2964 		mcp->mb[4] = LSW(word_count);
2965 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2966 	}
2967 	mcp->in_mb = MBX_0;
2968 	mcp->timeout = MAILBOX_TOV;
2969 	rval = ql_mailbox_command(ha, mcp);
2970 
2971 	if (rval != QL_SUCCESS) {
2972 		EL(ha, "failed, rval = %xh\n", rval);
2973 	} else {
2974 		/*EMPTY*/
2975 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2976 	}
2977 
2978 	return (rval);
2979 }
2980 
2981 /*
2982  * ql_wrt_risc_ram_word
2983  *	Write RISC RAM word.
2984  *
2985  * Input:
2986  *	ha:		adapter state pointer.
2987  *	risc_address:	risc ram word address.
2988  *	data:		data.
2989  *
2990  * Returns:
2991  *	ql local function return status code.
2992  *
2993  * Context:
2994  *	Kernel context.
2995  */
2996 int
ql_wrt_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t data)2997 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
2998     uint32_t data)
2999 {
3000 	int		rval;
3001 	mbx_cmd_t	mc = {0};
3002 	mbx_cmd_t	*mcp = &mc;
3003 
3004 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3005 
3006 	mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3007 	mcp->mb[1] = LSW(risc_address);
3008 	mcp->mb[2] = LSW(data);
3009 	mcp->mb[3] = MSW(data);
3010 	mcp->mb[8] = MSW(risc_address);
3011 	mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3012 	mcp->in_mb = MBX_0;
3013 	mcp->timeout = MAILBOX_TOV;
3014 
3015 	rval = ql_mailbox_command(ha, mcp);
3016 
3017 	if (rval != QL_SUCCESS) {
3018 		EL(ha, "failed, rval = %xh\n", rval);
3019 	} else {
3020 		/*EMPTY*/
3021 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
3022 	}
3023 
3024 	return (rval);
3025 }
3026 
3027 /*
3028  * ql_rd_risc_ram_word
3029  *	Read RISC RAM word.
3030  *
3031  * Input:
3032  *	ha:		adapter state pointer.
3033  *	risc_address:	risc ram word address.
3034  *	data:		data pointer.
3035  *
3036  * Returns:
3037  *	ql local function return status code.
3038  *
3039  * Context:
3040  *	Kernel context.
3041  */
3042 int
ql_rd_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t * data)3043