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 2015 QLogic Corporation */
23 
24 /*
25  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
26  */
27 
28 /*
29  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
30  *
31  * ***********************************************************************
32  * *									**
33  * *				NOTICE					**
34  * *		COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION		**
35  * *			ALL RIGHTS RESERVED				**
36  * *									**
37  * ***********************************************************************
38  *
39  */
40 
41 #include <ql_apps.h>
42 #include <ql_api.h>
43 #include <ql_debug.h>
44 #include <ql_iocb.h>
45 #include <ql_isr.h>
46 #include <ql_mbx.h>
47 #include <ql_nx.h>
48 #include <ql_xioctl.h>
49 
50 /*
51  * Local data
52  */
53 
54 /*
55  * Local prototypes
56  */
57 static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
58 static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint64_t,
59     uint32_t, uint16_t);
60 static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
61 static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
62     caddr_t, uint32_t);
63 static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
64     uint32_t);
65 static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
66 static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
67 static int ql_init_req_q(ql_adapter_state_t *, ql_request_q_t *, uint16_t);
68 static int ql_init_rsp_q(ql_adapter_state_t *, ql_response_q_t *, uint16_t);
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(ha, "started, cmd=%xh\n", 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 		if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
103 			EL(vha, "powerdown availability cmd=%xh\n", mcp->mb[0]);
104 			MBX_REGISTER_UNLOCK(ha);
105 			return (QL_LOCK_TIMEOUT);
106 		}
107 		ha->mailbox_flags = (uint8_t)
108 		    (ha->mailbox_flags | MBX_WANT_FLG);
109 
110 		/* Set timeout after command that is running. */
111 		timer = ha->mailbox_flags & MBX_BUSY_FLG ?
112 		    (mcp->timeout + 20) : 2;
113 		timer = timer * drv_usectohz(1000000);
114 		cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
115 		    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
116 		if (cv_stat == -1 || cv_stat == 0) {
117 			/*
118 			 * The timeout time 'timer' was
119 			 * reached without the condition
120 			 * being signaled.
121 			 */
122 			ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
123 			    ~MBX_WANT_FLG);
124 			cv_broadcast(&ha->cv_mbx_wait);
125 
126 			/* Release mailbox register lock. */
127 			MBX_REGISTER_UNLOCK(ha);
128 
129 			if (cv_stat == 0) {
130 				EL(vha, "waiting for availability aborted, "
131 				    "cmd=%xh\n", mcp->mb[0]);
132 				return (QL_ABORTED);
133 			}
134 			EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
135 			return (QL_LOCK_TIMEOUT);
136 		}
137 	}
138 
139 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
140 
141 	/* Structure pointer for return mailbox registers. */
142 	ha->mcp = mcp;
143 
144 	/* Load mailbox registers. */
145 	data = mcp->out_mb;
146 	for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
147 		if (data & MBX_0) {
148 			WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
149 		}
150 		data >>= 1;
151 	}
152 
153 	/* Issue set host interrupt command. */
154 	ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
155 	if (CFG_IST(ha, CFG_CTRL_82XX)) {
156 		WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
157 	} else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
158 		WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
159 	} else {
160 		WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
161 	}
162 
163 	/* Wait for command to complete. */
164 	if (ha->flags & INTERRUPTS_ENABLED &&
165 	    !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) &&
166 	    !ddi_in_panic()) {
167 		timer = mcp->timeout * drv_usectohz(1000000);
168 		while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
169 		    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
170 
171 			if (cv_reltimedwait(&ha->cv_mbx_intr,
172 			    &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
173 				/*
174 				 * The timeout time 'timer' was
175 				 * reached without the condition
176 				 * being signaled.
177 				 */
178 				EL(vha, "reltimedwait expired cmd=%xh\n",
179 				    mcp->mb[0]);
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_82XX)) {
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 (CFG_IST(ha, CFG_CTRL_22XX)) {
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(ha, "done\n");
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(ha, "started\n");
431 
432 	if (!CFG_IST(ha, CFG_FCIP_SUPPORT) || ha->vp_index != 0) {
433 		ha->flags &= ~IP_INITIALIZED;
434 		EL(ha, "HBA does not support IP\n");
435 		return (QL_FUNCTION_FAILED);
436 	}
437 
438 	ha->rcvbuf_ring_ptr = ha->rcv_ring.bp;
439 	ha->rcvbuf_ring_index = 0;
440 
441 	/* Reset all sequence counts. */
442 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
443 		for (link = ha->dev[index].first; link != NULL;
444 		    link = link->next) {
445 			tq = link->base_address;
446 			tq->ub_total_seg_cnt = 0;
447 		}
448 	}
449 
450 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
451 	    (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
452 	if (rval != QL_SUCCESS) {
453 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
454 		return (rval);
455 	}
456 
457 	mcp->mb[0] = MBC_INITIALIZE_IP;
458 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
459 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
460 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
461 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
462 	mcp->mb[8] = 0;
463 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
464 	mcp->in_mb = MBX_8|MBX_0;
465 	mcp->timeout = MAILBOX_TOV;
466 	rval = ql_mailbox_command(ha, mcp);
467 
468 	ql_free_dma_resource(ha, &mem_desc);
469 
470 	if (rval == QL_SUCCESS) {
471 		ADAPTER_STATE_LOCK(ha);
472 		ha->flags |= IP_INITIALIZED;
473 		ADAPTER_STATE_UNLOCK(ha);
474 		QL_PRINT_3(ha, "done\n");
475 	} else {
476 		ha->flags &= ~IP_INITIALIZED;
477 		EL(ha, "failed, rval = %xh\n", rval);
478 	}
479 	return (rval);
480 }
481 
482 /*
483  * ql_shutdown_ip
484  *	Disconnects firmware IP from system buffers.
485  *
486  * Input:
487  *	ha = adapter state pointer.
488  *
489  * Returns:
490  *	ql local function return status code.
491  *
492  * Context:
493  *	Kernel context.
494  */
495 int
ql_shutdown_ip(ql_adapter_state_t * ha)496 ql_shutdown_ip(ql_adapter_state_t *ha)
497 {
498 	int		rval;
499 	mbx_cmd_t	mc = {0};
500 	mbx_cmd_t	*mcp = &mc;
501 	fc_unsol_buf_t	*ubp;
502 	ql_srb_t	*sp;
503 	uint16_t	index;
504 
505 	QL_PRINT_3(ha, "started\n");
506 
507 	mcp->mb[0] = MBC_UNLOAD_IP;
508 	mcp->out_mb = MBX_0;
509 	mcp->in_mb = MBX_0;
510 	mcp->timeout = MAILBOX_TOV;
511 	rval = ql_mailbox_command(ha, mcp);
512 
513 	ADAPTER_STATE_LOCK(ha);
514 	QL_UB_LOCK(ha);
515 	/* Return all unsolicited buffers that ISP-IP has. */
516 	for (index = 0; index < QL_UB_LIMIT; index++) {
517 		ubp = ha->ub_array[index];
518 		if (ubp != NULL) {
519 			sp = ubp->ub_fca_private;
520 			sp->flags &= ~SRB_UB_IN_ISP;
521 		}
522 	}
523 
524 	ha->ub_outcnt = 0;
525 	QL_UB_UNLOCK(ha);
526 	ha->flags &= ~IP_INITIALIZED;
527 	ADAPTER_STATE_UNLOCK(ha);
528 
529 	if (rval == QL_SUCCESS) {
530 		/* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
531 		QL_PRINT_3(ha, "done\n");
532 	} else {
533 		EL(ha, "failed, rval = %xh\n", rval);
534 	}
535 	return (rval);
536 }
537 
538 /*
539  * ql_online_selftest
540  *	Issue online self test mailbox command.
541  *
542  * Input:
543  *	ha = adapter state pointer.
544  *
545  * Returns:
546  *	ql local function return status code.
547  *
548  * Context:
549  *	Kernel context.
550  */
551 int
ql_online_selftest(ql_adapter_state_t * ha)552 ql_online_selftest(ql_adapter_state_t *ha)
553 {
554 	int		rval;
555 	mbx_cmd_t	mc = {0};
556 	mbx_cmd_t	*mcp = &mc;
557 
558 	QL_PRINT_3(ha, "started\n");
559 
560 	mcp->mb[0] = MBC_ONLINE_SELF_TEST;
561 	mcp->out_mb = MBX_0;
562 	mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
563 	mcp->timeout = MAILBOX_TOV;
564 	rval = ql_mailbox_command(ha, mcp);
565 
566 	if (rval != QL_SUCCESS) {
567 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
568 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
569 	} else {
570 		/*EMPTY*/
571 		QL_PRINT_3(ha, "done\n");
572 	}
573 	return (rval);
574 }
575 
576 /*
577  * ql_loop_back
578  *	Issue diagnostic loop back frame mailbox command.
579  *
580  * Input:
581  *	ha:	adapter state pointer.
582  *	findex:	FCF index.
583  *	lb:	loop back parameter structure pointer.
584  *
585  * Returns:
586  *	ql local function return status code.
587  *
588  * Context:
589  *	Kernel context.
590  */
591 #ifndef apps_64bit
592 int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb,uint32_t h_xmit,uint32_t h_rcv)593 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
594     uint32_t h_xmit, uint32_t h_rcv)
595 {
596 	int		rval;
597 	mbx_cmd_t	mc = {0};
598 	mbx_cmd_t	*mcp = &mc;
599 
600 	QL_PRINT_3(ha, "started\n");
601 
602 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
603 	mcp->mb[1] = lb->options;
604 	mcp->mb[2] = findex;
605 	mcp->mb[6] = LSW(h_rcv);
606 	mcp->mb[7] = MSW(h_rcv);
607 	mcp->mb[10] = LSW(lb->transfer_count);
608 	mcp->mb[11] = MSW(lb->transfer_count);
609 	mcp->mb[12] = lb->transfer_segment_count;
610 	mcp->mb[13] = lb->receive_segment_count;
611 	mcp->mb[14] = LSW(lb->transfer_data_address);
612 	mcp->mb[15] = MSW(lb->transfer_data_address);
613 	mcp->mb[16] = LSW(lb->receive_data_address);
614 	mcp->mb[17] = MSW(lb->receive_data_address);
615 	mcp->mb[18] = LSW(lb->iteration_count);
616 	mcp->mb[19] = MSW(lb->iteration_count);
617 	mcp->mb[20] = LSW(h_xmit);
618 	mcp->mb[21] = MSW(h_xmit);
619 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
620 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
621 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
622 	mcp->timeout = lb->iteration_count / 300;
623 
624 	if (mcp->timeout < MAILBOX_TOV) {
625 		mcp->timeout = MAILBOX_TOV;
626 	}
627 
628 	rval = ql_mailbox_command(ha, mcp);
629 
630 	if (rval != QL_SUCCESS) {
631 		EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
632 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
633 	} else {
634 		/*EMPTY*/
635 		QL_PRINT_3(ha, "done\n");
636 	}
637 	return (rval);
638 }
639 #else
640 int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb)641 ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
642 {
643 	int		rval;
644 	mbx_cmd_t	mc = {0};
645 	mbx_cmd_t	*mcp = &mc;
646 
647 	QL_PRINT_3(ha, "started\n");
648 
649 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
650 	mcp->mb[1] = lb->options;
651 	mcp->mb[2] = findex;
652 	mcp->mb[6] = LSW(h_rcv);
653 	mcp->mb[7] = MSW(h_rcv);
654 	mcp->mb[6] = LSW(MSD(lb->receive_data_address));
655 	mcp->mb[7] = MSW(MSD(lb->receive_data_address));
656 	mcp->mb[10] = LSW(lb->transfer_count);
657 	mcp->mb[11] = MSW(lb->transfer_count);
658 	mcp->mb[12] = lb->transfer_segment_count;
659 	mcp->mb[13] = lb->receive_segment_count;
660 	mcp->mb[14] = LSW(lb->transfer_data_address);
661 	mcp->mb[15] = MSW(lb->transfer_data_address);
662 	mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
663 	mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
664 	mcp->mb[16] = LSW(lb->receive_data_address);
665 	mcp->mb[17] = MSW(lb->receive_data_address);
666 	mcp->mb[16] = LSW(LSD(lb->receive_data_address));
667 	mcp->mb[17] = MSW(LSD(lb->receive_data_address));
668 	mcp->mb[18] = LSW(lb->iteration_count);
669 	mcp->mb[19] = MSW(lb->iteration_count);
670 	mcp->mb[20] = LSW(h_xmit);
671 	mcp->mb[21] = MSW(h_xmit);
672 	mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
673 	mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
674 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
675 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
676 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
677 	mcp->timeout = lb->iteration_count / 300;
678 
679 	if (mcp->timeout < MAILBOX_TOV) {
680 		mcp->timeout = MAILBOX_TOV;
681 	}
682 
683 	rval = ql_mailbox_command(ha, mcp);
684 
685 	if (rval != QL_SUCCESS) {
686 		EL(ha, "failed, rval = %xh\n", rval);
687 	} else {
688 		/*EMPTY*/
689 		QL_PRINT_3(ha, "done\n");
690 	}
691 	return (rval);
692 }
693 #endif
694 
695 /*
696  * ql_echo
697  *	Issue an ELS echo using the user specified data to a user specified
698  *	destination
699  *
700  * Input:
701  *	ha:		adapter state pointer.
702  *	findex:		FCF index.
703  *	echo_pt:	echo parameter structure pointer.
704  *
705  * Returns:
706  *	ql local function return status code.
707  *
708  * Context:
709  *	Kernel context.
710  */
711 int
ql_echo(ql_adapter_state_t * ha,uint16_t findex,echo_t * echo_pt)712 ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
713 {
714 	int		rval;
715 	mbx_cmd_t	mc = {0};
716 	mbx_cmd_t	*mcp = &mc;
717 
718 	QL_PRINT_3(ha, "started\n");
719 
720 	mcp->mb[0] = MBC_ECHO;			/* ECHO command */
721 	mcp->mb[1] = echo_pt->options;		/* command options; 64 bit */
722 						/* addressing (bit 6) and */
723 						/* real echo (bit 15 */
724 	mcp->mb[2] = findex;
725 
726 	/*
727 	 * I know this looks strange, using a field labled "not used"
728 	 * The way the ddi_dma_cookie_t structure/union is defined
729 	 * is a union of one 64 bit entity with an array of two 32
730 	 * bit enititys.  Since we have routines to convert 32 bit
731 	 * entities into 16 bit entities it is easier to use
732 	 * both 32 bit union members then the one 64 bit union
733 	 * member
734 	 */
735 	if (echo_pt->options & BIT_6) {
736 		/* 64 bit addressing */
737 		/* Receive data dest add in system memory bits 47-32 */
738 		mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
739 
740 		/* Receive data dest add in system memory bits 63-48 */
741 		mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
742 
743 		/* Transmit data source address in system memory bits 47-32 */
744 		mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
745 
746 		/* Transmit data source address in system memory bits 63-48 */
747 		mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
748 	}
749 
750 	/* transfer count bits 15-0 */
751 	mcp->mb[10] = LSW(echo_pt->transfer_count);
752 
753 	/* Transmit data source address in system memory bits 15-0 */
754 	mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
755 
756 	/*  Transmit data source address in system memory bits 31-16 */
757 	mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
758 
759 	/* Receive data destination address in system memory bits 15-0 */
760 	mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
761 
762 	/*  Receive data destination address in system memory bits 31-16 */
763 	mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
764 
765 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
766 	    MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
767 	mcp->in_mb = MBX_3|MBX_1|MBX_0;
768 	mcp->timeout = MAILBOX_TOV;
769 
770 	rval = ql_mailbox_command(ha, mcp);
771 
772 	if (rval != QL_SUCCESS) {
773 		EL(ha, "failed, rval = %xh\n", rval);
774 	} else {
775 		/*EMPTY*/
776 		QL_PRINT_3(ha, "done\n");
777 	}
778 	return (rval);
779 }
780 
781 /*
782  * ql_send_change_request
783  *	Issue send change request mailbox command.
784  *
785  * Input:
786  *	ha:	adapter state pointer.
787  *	fmt:	Registration format.
788  *
789  * Returns:
790  *	ql local function return status code.
791  *
792  * Context:
793  *	Kernel context.
794  */
795 int
ql_send_change_request(ql_adapter_state_t * ha,uint16_t fmt)796 ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
797 {
798 	int		rval;
799 	mbx_cmd_t	mc = {0};
800 	mbx_cmd_t	*mcp = &mc;
801 
802 	QL_PRINT_3(ha, "started\n");
803 
804 	mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
805 	mcp->mb[1] = fmt;
806 	mcp->out_mb = MBX_1|MBX_0;
807 	if (ha->flags & VP_ENABLED) {
808 		mcp->mb[9] = ha->vp_index;
809 		mcp->out_mb |= MBX_9;
810 	}
811 	mcp->in_mb = MBX_0;
812 	mcp->timeout = MAILBOX_TOV;
813 	rval = ql_mailbox_command(ha, mcp);
814 
815 	if (rval != QL_SUCCESS) {
816 		EL(ha, "failed=%xh\n", rval);
817 	} else {
818 		/*EMPTY*/
819 		QL_PRINT_3(ha, "done\n");
820 	}
821 	return (rval);
822 }
823 
824 /*
825  * ql_send_lfa
826  *	Send a Loop Fabric Address mailbox command.
827  *
828  * Input:
829  *	ha:	adapter state pointer.
830  *	lfa:	LFA command structure pointer.
831  *
832  * Returns:
833  *	ql local function return status code.
834  *
835  * Context:
836  *	Kernel context.
837  */
838 int
ql_send_lfa(ql_adapter_state_t * ha,lfa_cmd_t * lfa)839 ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
840 {
841 	int		rval;
842 	uint16_t	size;
843 	dma_mem_t	mem_desc;
844 	mbx_cmd_t	mc = {0};
845 	mbx_cmd_t	*mcp = &mc;
846 
847 	QL_PRINT_3(ha, "started\n");
848 
849 	/* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
850 	size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
851 
852 	rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
853 	if (rval != QL_SUCCESS) {
854 		EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
855 		return (rval);
856 	}
857 
858 	mcp->mb[0] = MBC_SEND_LFA_COMMAND;
859 	mcp->mb[1] = (uint16_t)(size >> 1);
860 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
861 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
862 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
863 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
864 	mcp->in_mb = MBX_0;
865 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
866 	if (ha->flags & VP_ENABLED) {
867 		mcp->mb[9] = ha->vp_index;
868 		mcp->out_mb |= MBX_9;
869 	}
870 	mcp->timeout = MAILBOX_TOV;
871 	rval = ql_mailbox_command(ha, mcp);
872 
873 	ql_free_dma_resource(ha, &mem_desc);
874 
875 	if (rval != QL_SUCCESS) {
876 		EL(ha, "failed, rval = %xh\n", rval);
877 	} else {
878 		/*EMPTY*/
879 		QL_PRINT_3(ha, "done\n");
880 	}
881 
882 	return (rval);
883 }
884 
885 /*
886  * ql_clear_aca
887  *	Issue clear ACA mailbox command.
888  *
889  * Input:
890  *	ha:	adapter state pointer.
891  *	tq:	target queue pointer.
892  *	lq:	LUN queue pointer.
893  *
894  * Returns:
895  *	ql local function return status code.
896  *
897  * Context:
898  *	Kernel context.
899  */
900 int
ql_clear_aca(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)901 ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
902 {
903 	int		rval;
904 	mbx_cmd_t	mc = {0};
905 	mbx_cmd_t	*mcp = &mc;
906 
907 	QL_PRINT_3(ha, "started\n");
908 
909 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
910 		rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
911 		    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] = lq->lun_no;
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, lq, 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(ha, "done\n");
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 	ql_srb_t	*sp;
958 	uint16_t	index;
959 	int		rval = QL_SUCCESS;
960 	mbx_cmd_t	mc = {0};
961 	mbx_cmd_t	*mcp = &mc;
962 
963 	QL_PRINT_3(ha, "started\n");
964 
965 	ql_requeue_pending_cmds(ha, tq);
966 	INTR_LOCK(ha);
967 	for (index = 1; index < ha->pha->osc_max_cnt; index++) {
968 		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
969 		    sp->lun_queue != NULL &&
970 		    sp->lun_queue->target_queue == tq) {
971 			sp->flags |= SRB_ABORTING;
972 		}
973 	}
974 	INTR_UNLOCK(ha);
975 
976 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
977 		/* queue = NULL, all targets. */
978 		if (tq == NULL) {
979 			for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
980 			    index++) {
981 				for (link = ha->dev[index].first; link !=
982 				    NULL; link = link->next) {
983 					tq = link->base_address;
984 					if (!VALID_DEVICE_ID(ha,
985 					    tq->loop_id)) {
986 						continue;
987 					}
988 
989 					if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
990 						rval = ql_task_mgmt_iocb(ha,
991 						    tq, 0, CF_DO_NOT_SEND |
992 						    CF_TARGET_RESET, delay);
993 					} else {
994 						rval = ql_task_mgmt_iocb(ha,
995 						    tq, 0, CF_TARGET_RESET,
996 						    delay);
997 					}
998 
999 					if (rval != QL_SUCCESS) {
1000 						break;
1001 					}
1002 				}
1003 
1004 				if (link != NULL) {
1005 					break;
1006 				}
1007 			}
1008 			tq = NULL;
1009 		} else {
1010 
1011 			if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1012 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1013 				    CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
1014 			} else {
1015 				rval = ql_task_mgmt_iocb(ha, tq, 0,
1016 				    CF_TARGET_RESET, delay);
1017 			}
1018 		}
1019 	} else {
1020 		/* queue = NULL, all targets. */
1021 		if (tq == NULL) {
1022 			mcp->mb[0] = MBC_RESET;
1023 			mcp->mb[1] = delay;
1024 			mcp->out_mb = MBX_1|MBX_0;
1025 		} else {
1026 			mcp->mb[0] = MBC_TARGET_RESET;
1027 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1028 				mcp->mb[1] = tq->loop_id;
1029 			} else {
1030 				mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1031 			}
1032 			mcp->mb[2] = delay;
1033 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1034 		}
1035 		mcp->in_mb = MBX_0;
1036 		mcp->timeout = MAILBOX_TOV;
1037 		rval = ql_mailbox_command(ha, mcp);
1038 	}
1039 
1040 	tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1041 	    (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1042 
1043 	if (rval != QL_SUCCESS) {
1044 		EL(ha, "failed, rval = %xh\n", rval);
1045 	} else {
1046 		/*EMPTY*/
1047 		QL_PRINT_3(ha, "done\n");
1048 	}
1049 
1050 	return (rval);
1051 }
1052 
1053 /*
1054  * ql_abort_target
1055  *	Issue abort target mailbox command.
1056  *
1057  * Input:
1058  *	ha:	adapter state pointer.
1059  *	tq:	target queue pointer.
1060  *	delay:	in seconds.
1061  *
1062  * Returns:
1063  *	ql local function return status code.
1064  *
1065  * Context:
1066  *	Kernel context.
1067  */
1068 int
ql_abort_target(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t delay)1069 ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1070 {
1071 	ql_srb_t	*sp;
1072 	uint16_t	index;
1073 	int		rval;
1074 	mbx_cmd_t	mc = {0};
1075 	mbx_cmd_t	*mcp = &mc;
1076 
1077 	QL_PRINT_3(ha, "started\n");
1078 
1079 	ql_requeue_pending_cmds(ha, tq);
1080 	INTR_LOCK(ha);
1081 	for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1082 		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1083 		    sp->lun_queue != NULL &&
1084 		    sp->lun_queue->target_queue == tq) {
1085 			sp->flags |= SRB_ABORTING;
1086 		}
1087 	}
1088 	INTR_UNLOCK(ha);
1089 
1090 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1091 		rval = ql_task_mgmt_iocb(ha, tq, 0,
1092 		    CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1093 	} else {
1094 		mcp->mb[0] = MBC_ABORT_TARGET;
1095 		/* Don't send Task Mgt */
1096 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1097 			mcp->mb[1] = tq->loop_id;
1098 			mcp->mb[10] = BIT_0;
1099 			mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1100 		} else {
1101 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1102 			mcp->out_mb = MBX_2|MBX_1|MBX_0;
1103 		}
1104 		mcp->mb[2] = delay;
1105 		mcp->in_mb = MBX_0;
1106 		mcp->timeout = MAILBOX_TOV;
1107 		rval = ql_mailbox_command(ha, mcp);
1108 	}
1109 
1110 	(void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1111 
1112 	if (rval != QL_SUCCESS) {
1113 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1114 	} else {
1115 		/*EMPTY*/
1116 		QL_PRINT_3(ha, "done\n");
1117 	}
1118 	return (rval);
1119 }
1120 
1121 /*
1122  * ql_lun_reset
1123  *	Issue LUN reset task management mailbox command.
1124  *
1125  * Input:
1126  *	ha:	adapter state pointer.
1127  *	tq:	target queue pointer.
1128  *	lq:	LUN queue pointer.
1129  *
1130  * Returns:
1131  *	ql local function return status code.
1132  *
1133  * Context:
1134  *	Kernel context.
1135  */
1136 int
ql_lun_reset(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1137 ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1138 {
1139 	ql_srb_t	*sp;
1140 	uint16_t	index;
1141 	int		rval;
1142 	mbx_cmd_t	mc = {0};
1143 	mbx_cmd_t	*mcp = &mc;
1144 
1145 	QL_PRINT_3(ha, "started\n");
1146 
1147 	ql_requeue_pending_cmds(ha, tq);
1148 	INTR_LOCK(ha);
1149 	for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1150 		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1151 		    sp->lun_queue != NULL &&
1152 		    sp->lun_queue->target_queue == tq &&
1153 		    sp->lun_queue == lq) {
1154 			sp->flags |= SRB_ABORTING;
1155 		}
1156 	}
1157 	INTR_UNLOCK(ha);
1158 
1159 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1160 		rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1161 		    CF_LUN_RESET, 0);
1162 	} else {
1163 		mcp->mb[0] = MBC_LUN_RESET;
1164 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1165 			mcp->mb[1] = tq->loop_id;
1166 		} else {
1167 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1168 		}
1169 		mcp->mb[2] = lq->lun_no;
1170 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1171 		mcp->in_mb = MBX_0;
1172 		mcp->timeout = MAILBOX_TOV;
1173 		rval = ql_mailbox_command(ha, mcp);
1174 	}
1175 
1176 	(void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1177 
1178 	if (rval != QL_SUCCESS) {
1179 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1180 	} else {
1181 		/*EMPTY*/
1182 		QL_PRINT_3(ha, "done\n");
1183 	}
1184 	return (rval);
1185 }
1186 
1187 /*
1188  * ql_clear_task_set
1189  *	Issue clear task set mailbox command.
1190  *
1191  * Input:
1192  *	ha:	adapter state pointer.
1193  *	tq:	target queue pointer.
1194  *	lq:	LUN queue pointer.
1195  *
1196  * Returns:
1197  *	ql local function return status code.
1198  *
1199  * Context:
1200  *	Kernel context.
1201  */
1202 int
ql_clear_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1203 ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1204 {
1205 	ql_srb_t	*sp;
1206 	uint16_t	index;
1207 	int		rval;
1208 	mbx_cmd_t	mc = {0};
1209 	mbx_cmd_t	*mcp = &mc;
1210 
1211 	QL_PRINT_3(ha, "started\n");
1212 
1213 	ql_requeue_pending_cmds(ha, tq);
1214 	INTR_LOCK(ha);
1215 	for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1216 		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1217 		    sp->lun_queue != NULL &&
1218 		    sp->lun_queue->target_queue == tq &&
1219 		    sp->lun_queue == lq) {
1220 			sp->flags |= SRB_ABORTING;
1221 		}
1222 	}
1223 	INTR_UNLOCK(ha);
1224 
1225 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1226 		rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1227 		    CF_CLEAR_TASK_SET, 0);
1228 	} else {
1229 		mcp->mb[0] = MBC_CLEAR_TASK_SET;
1230 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1231 			mcp->mb[1] = tq->loop_id;
1232 		} else {
1233 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1234 		}
1235 		mcp->mb[2] = lq->lun_no;
1236 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1237 		mcp->in_mb = MBX_0;
1238 		mcp->timeout = MAILBOX_TOV;
1239 		rval = ql_mailbox_command(ha, mcp);
1240 	}
1241 
1242 	(void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1243 
1244 	if (rval != QL_SUCCESS) {
1245 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1246 	} else {
1247 		/*EMPTY*/
1248 		QL_PRINT_3(ha, "done\n");
1249 	}
1250 
1251 	return (rval);
1252 }
1253 
1254 /*
1255  * ql_abort_task_set
1256  *	Issue abort task set mailbox command.
1257  *
1258  * Input:
1259  *	ha:	adapter state pointer.
1260  *	tq:	target queue pointer.
1261  *	lq:	LUN queue pointer.
1262  *
1263  * Returns:
1264  *	ql local function return status code.
1265  *
1266  * Context:
1267  *	Kernel context.
1268  */
1269 int
ql_abort_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1270 ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1271 {
1272 	ql_srb_t	*sp;
1273 	uint16_t	index;
1274 	int		rval;
1275 	mbx_cmd_t	mc = {0};
1276 	mbx_cmd_t	*mcp = &mc;
1277 
1278 	QL_PRINT_3(ha, "started\n");
1279 
1280 	ql_requeue_pending_cmds(ha, tq);
1281 	INTR_LOCK(ha);
1282 	for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1283 		if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1284 		    sp->lun_queue != NULL &&
1285 		    sp->lun_queue->target_queue == tq &&
1286 		    sp->lun_queue == lq) {
1287 			sp->flags |= SRB_ABORTING;
1288 		}
1289 	}
1290 	INTR_UNLOCK(ha);
1291 
1292 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1293 		rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1294 		    CF_ABORT_TASK_SET, 0);
1295 	} else {
1296 		mcp->mb[0] = MBC_ABORT_TASK_SET;
1297 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1298 			mcp->mb[1] = tq->loop_id;
1299 		} else {
1300 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1301 		}
1302 		mcp->mb[2] = lq->lun_no;
1303 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1304 		mcp->in_mb = MBX_0;
1305 		mcp->timeout = MAILBOX_TOV;
1306 		rval = ql_mailbox_command(ha, mcp);
1307 	}
1308 
1309 	(void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1310 
1311 	if (rval != QL_SUCCESS) {
1312 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1313 	} else {
1314 		/*EMPTY*/
1315 		QL_PRINT_3(ha, "done\n");
1316 	}
1317 
1318 	return (rval);
1319 }
1320 
1321 /*
1322  * ql_task_mgmt_iocb
1323  *	Function issues task management IOCB.
1324  *
1325  * Input:
1326  *	ha:		adapter state pointer.
1327  *	tq:		target queue pointer.
1328  *	lun_addr:	LUN.
1329  *	flags:		control flags.
1330  *	delay:		seconds.
1331  *
1332  * Returns:
1333  *	ql local function return status code.
1334  *
1335  * Context:
1336  *	Kernel context
1337  */
1338 static int
ql_task_mgmt_iocb(ql_adapter_state_t * ha,ql_tgt_t * tq,uint64_t lun_addr,uint32_t flags,uint16_t delay)1339 ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint64_t lun_addr,
1340     uint32_t flags, uint16_t delay)
1341 {
1342 	ql_mbx_iocb_t	*pkt;
1343 	int		rval;
1344 	uint32_t	pkt_size;
1345 	fcp_ent_addr_t	*fcp_ent_addr;
1346 
1347 	QL_PRINT_3(ha, "started\n");
1348 
1349 	pkt_size = sizeof (ql_mbx_iocb_t);
1350 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1351 	if (pkt == NULL) {
1352 		EL(ha, "failed, kmem_zalloc\n");
1353 		return (QL_MEMORY_ALLOC_FAILED);
1354 	}
1355 
1356 	pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1357 	pkt->mgmt.entry_count = 1;
1358 
1359 	pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1360 	pkt->mgmt.delay = (uint16_t)LE_16(delay);
1361 	pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1362 
1363 	fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr;
1364 	pkt->mgmt.fcp_lun[2] = lobyte(fcp_ent_addr->ent_addr_0);
1365 	pkt->mgmt.fcp_lun[3] = hibyte(fcp_ent_addr->ent_addr_0);
1366 	pkt->mgmt.fcp_lun[0] = lobyte(fcp_ent_addr->ent_addr_1);
1367 	pkt->mgmt.fcp_lun[1] = hibyte(fcp_ent_addr->ent_addr_1);
1368 	pkt->mgmt.fcp_lun[6] = lobyte(fcp_ent_addr->ent_addr_2);
1369 	pkt->mgmt.fcp_lun[7] = hibyte(fcp_ent_addr->ent_addr_2);
1370 	pkt->mgmt.fcp_lun[4] = lobyte(fcp_ent_addr->ent_addr_3);
1371 	pkt->mgmt.fcp_lun[5] = hibyte(fcp_ent_addr->ent_addr_3);
1372 
1373 	pkt->mgmt.control_flags = LE_32(flags);
1374 	pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1375 	pkt->mgmt.target_id[1] = tq->d_id.b.area;
1376 	pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1377 	pkt->mgmt.vp_index = ha->vp_index;
1378 
1379 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1380 	if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1381 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1382 		    pkt->sts24.entry_status, tq->d_id.b24);
1383 		rval = QL_FUNCTION_PARAMETER_ERROR;
1384 	}
1385 
1386 	LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1387 
1388 	if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1389 		EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1390 		    pkt->sts24.comp_status, tq->d_id.b24);
1391 		rval = QL_FUNCTION_FAILED;
1392 	}
1393 
1394 	kmem_free(pkt, pkt_size);
1395 
1396 	if (rval != QL_SUCCESS) {
1397 		EL(ha, "failed, rval = %xh\n", rval);
1398 	} else {
1399 		/*EMPTY*/
1400 		QL_PRINT_3(ha, "done\n");
1401 	}
1402 
1403 	return (rval);
1404 }
1405 
1406 /*
1407  * ql_loop_port_bypass
1408  *	Issue loop port bypass mailbox command.
1409  *
1410  * Input:
1411  *	ha:	adapter state pointer.
1412  *	tq:	target queue pointer.
1413  *
1414  * Returns:
1415  *	ql local function return status code.
1416  *
1417  * Context:
1418  *	Kernel context.
1419  */
1420 int
ql_loop_port_bypass(ql_adapter_state_t * ha,ql_tgt_t * tq)1421 ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1422 {
1423 	int		rval;
1424 	mbx_cmd_t	mc = {0};
1425 	mbx_cmd_t	*mcp = &mc;
1426 
1427 	QL_PRINT_3(ha, "started\n");
1428 
1429 	mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1430 
1431 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1432 		mcp->mb[1] = tq->d_id.b.al_pa;
1433 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1434 		mcp->mb[1] = tq->loop_id;
1435 	} else {
1436 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1437 	}
1438 
1439 	mcp->out_mb = MBX_1|MBX_0;
1440 	mcp->in_mb = MBX_0;
1441 	mcp->timeout = MAILBOX_TOV;
1442 	rval = ql_mailbox_command(ha, mcp);
1443 
1444 	if (rval != QL_SUCCESS) {
1445 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1446 	} else {
1447 		/*EMPTY*/
1448 		QL_PRINT_3(ha, "done\n");
1449 	}
1450 
1451 	return (rval);
1452 }
1453 
1454 /*
1455  * ql_loop_port_enable
1456  *	Issue loop port enable mailbox command.
1457  *
1458  * Input:
1459  *	ha:	adapter state pointer.
1460  *	tq:	target queue pointer.
1461  *
1462  * Returns:
1463  *	ql local function return status code.
1464  *
1465  * Context:
1466  *	Kernel context.
1467  */
1468 int
ql_loop_port_enable(ql_adapter_state_t * ha,ql_tgt_t * tq)1469 ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1470 {
1471 	int		rval;
1472 	mbx_cmd_t	mc = {0};
1473 	mbx_cmd_t	*mcp = &mc;
1474 
1475 	QL_PRINT_3(ha, "started\n");
1476 
1477 	mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1478 
1479 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1480 		mcp->mb[1] = tq->d_id.b.al_pa;
1481 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1482 		mcp->mb[1] = tq->loop_id;
1483 	} else {
1484 		mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1485 	}
1486 	mcp->out_mb = MBX_1|MBX_0;
1487 	mcp->in_mb = MBX_0;
1488 	mcp->timeout = MAILBOX_TOV;
1489 	rval = ql_mailbox_command(ha, mcp);
1490 
1491 	if (rval != QL_SUCCESS) {
1492 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1493 	} else {
1494 		/*EMPTY*/
1495 		QL_PRINT_3(ha, "done\n");
1496 	}
1497 
1498 	return (rval);
1499 }
1500 
1501 /*
1502  * ql_login_lport
1503  *	Issue login loop port mailbox command.
1504  *
1505  * Input:
1506  *	ha:		adapter state pointer.
1507  *	tq:		target queue pointer.
1508  *	loop_id:	FC loop id.
1509  *	opt:		options.
1510  *			LLF_NONE, LLF_PLOGI
1511  *
1512  * Returns:
1513  *	ql local function return status code.
1514  *
1515  * Context:
1516  *	Kernel context.
1517  */
1518 int
ql_login_lport(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t opt)1519 ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1520     uint16_t opt)
1521 {
1522 	int		rval;
1523 	uint16_t	flags;
1524 	ql_mbx_data_t	mr;
1525 	mbx_cmd_t	mc = {0};
1526 	mbx_cmd_t	*mcp = &mc;
1527 
1528 	QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1529 	    ha->instance, tq->d_id.b24, loop_id);
1530 
1531 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1532 		flags = CF_CMD_PLOGI;
1533 		if ((opt & LLF_PLOGI) == 0) {
1534 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1535 		}
1536 		rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1537 	} else {
1538 		mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1539 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1540 			mcp->mb[1] = loop_id;
1541 		} else {
1542 			mcp->mb[1] = (uint16_t)(loop_id << 8);
1543 		}
1544 		mcp->mb[2] = opt;
1545 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
1546 		mcp->in_mb = MBX_0;
1547 		mcp->timeout = MAILBOX_TOV;
1548 		rval = ql_mailbox_command(ha, mcp);
1549 	}
1550 
1551 	if (rval != QL_SUCCESS) {
1552 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1553 		    loop_id, rval);
1554 	} else {
1555 		/*EMPTY*/
1556 		QL_PRINT_3(ha, "done\n");
1557 	}
1558 
1559 	return (rval);
1560 }
1561 
1562 /*
1563  * ql_login_fport
1564  *	Issue login fabric port mailbox command.
1565  *
1566  * Input:
1567  *	ha:		adapter state pointer.
1568  *	tq:		target queue pointer.
1569  *	loop_id:	FC loop id.
1570  *	opt:		options.
1571  *			LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1572  *	mr:		pointer for mailbox data.
1573  *
1574  * Returns:
1575  *	ql local function return status code.
1576  *
1577  * Context:
1578  *	Kernel context.
1579  */
1580 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)1581 ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1582     uint16_t opt, ql_mbx_data_t *mr)
1583 {
1584 	int		rval;
1585 	uint16_t	flags;
1586 	mbx_cmd_t	mc = {0};
1587 	mbx_cmd_t	*mcp = &mc;
1588 
1589 	QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1590 	    ha->instance, tq->d_id.b24, loop_id);
1591 
1592 	if ((tq->d_id.b24 & QL_PORT_ID_MASK) == FS_MANAGEMENT_SERVER) {
1593 		opt = (uint16_t)(opt | LFF_NO_PRLI);
1594 	}
1595 
1596 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1597 		flags = CF_CMD_PLOGI;
1598 		if (opt & LFF_NO_PLOGI) {
1599 			flags = (uint16_t)(flags | CFO_COND_PLOGI);
1600 		}
1601 		if (opt & LFF_NO_PRLI) {
1602 			flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1603 		}
1604 		rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1605 	} else {
1606 		mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1607 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1608 			mcp->mb[1] = loop_id;
1609 			mcp->mb[10] = opt;
1610 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1611 		} else {
1612 			mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1613 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1614 		}
1615 		mcp->mb[2] = MSW(tq->d_id.b24);
1616 		mcp->mb[3] = LSW(tq->d_id.b24);
1617 		mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1618 		mcp->timeout = MAILBOX_TOV;
1619 		rval = ql_mailbox_command(ha, mcp);
1620 
1621 		/* Return mailbox data. */
1622 		if (mr != NULL) {
1623 			mr->mb[0] = mcp->mb[0];
1624 			mr->mb[1] = mcp->mb[1];
1625 			mr->mb[2] = mcp->mb[2];
1626 			mr->mb[6] = mcp->mb[6];
1627 			mr->mb[7] = mcp->mb[7];
1628 		}
1629 	}
1630 
1631 	if (rval != QL_SUCCESS) {
1632 		EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1633 		    "mb2=%04x\n", tq->d_id.b24, loop_id, rval,
1634 		    mr != NULL ? mr->mb[1] : mcp->mb[1],
1635 		    mr != NULL ? mr->mb[2] : mcp->mb[2]);
1636 	} else {
1637 		/*EMPTY*/
1638 		QL_PRINT_3(ha, "done\n");
1639 	}
1640 
1641 	return (rval);
1642 }
1643 
1644 /*
1645  * ql_logout_fabric_port
1646  *	Issue logout fabric port mailbox command.
1647  *
1648  * Input:
1649  *	ha:	adapter state pointer.
1650  *	tq:	target queue pointer.
1651  *
1652  * Returns:
1653  *	ql local function return status code.
1654  *
1655  * Context:
1656  *	Kernel context.
1657  */
1658 int
ql_logout_fabric_port(ql_adapter_state_t * ha,ql_tgt_t * tq)1659 ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1660 {
1661 	int		rval;
1662 	uint16_t	flag;
1663 	ql_mbx_data_t	mr;
1664 	mbx_cmd_t	mc = {0};
1665 	mbx_cmd_t	*mcp = &mc;
1666 
1667 	QL_PRINT_3(ha, "started, loop_id=%xh d_id=%xh\n",
1668 	    tq->loop_id, tq->d_id.b24);
1669 
1670 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1671 		if ((ha->topology & QL_N_PORT) &&
1672 		    (tq->loop_id != 0x7fe) &&
1673 		    (tq->loop_id != 0x7ff)) {
1674 			flag = (uint16_t)(CFO_IMPLICIT_LOGO |
1675 			    CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1676 
1677 			rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1678 		} else {
1679 			flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1680 			    CFO_EXPLICIT_LOGO | CF_CMD_LOGO |
1681 			    CFO_FREE_N_PORT_HANDLE :
1682 			    CFO_IMPLICIT_LOGO | CF_CMD_LOGO |
1683 			    CFO_FREE_N_PORT_HANDLE);
1684 
1685 			rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1686 		}
1687 
1688 		if (rval == QL_SUCCESS) {
1689 			EL(ha, "tq=%ph, loop_id=%xh, d_id=%xh, flag=%xh\n",
1690 			    tq, tq->loop_id, tq->d_id.b24, flag);
1691 		}
1692 	} else {
1693 		flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0);
1694 		mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1695 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1696 			mcp->mb[1] = tq->loop_id;
1697 			mcp->mb[10] = flag;
1698 			mcp->out_mb = MBX_10|MBX_1|MBX_0;
1699 		} else {
1700 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1701 			mcp->out_mb = MBX_1|MBX_0;
1702 		}
1703 		mcp->in_mb = MBX_0;
1704 		mcp->timeout = MAILBOX_TOV;
1705 		rval = ql_mailbox_command(ha, mcp);
1706 	}
1707 
1708 	if (rval != QL_SUCCESS) {
1709 		EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n", rval,
1710 		    tq->d_id.b24, tq->loop_id);
1711 	} else {
1712 		/*EMPTY*/
1713 		QL_PRINT_3(ha, "done\n");
1714 	}
1715 
1716 	return (rval);
1717 }
1718 
1719 /*
1720  * ql_log_iocb
1721  *	Function issues login/logout IOCB.
1722  *
1723  * Input:
1724  *	ha:		adapter state pointer.
1725  *	tq:		target queue pointer.
1726  *	loop_id:	FC Loop ID.
1727  *	flags:		control flags.
1728  *	mr:		pointer for mailbox data.
1729  *
1730  * Returns:
1731  *	ql local function return status code.
1732  *
1733  * Context:
1734  *	Kernel context.
1735  */
1736 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)1737 ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1738     uint16_t flags, ql_mbx_data_t *mr)
1739 {
1740 	ql_mbx_iocb_t	*pkt;
1741 	int		rval;
1742 	uint32_t	pkt_size;
1743 
1744 	QL_PRINT_3(ha, "started\n");
1745 
1746 	pkt_size = sizeof (ql_mbx_iocb_t);
1747 	pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1748 	if (pkt == NULL) {
1749 		EL(ha, "failed, kmem_zalloc\n");
1750 		return (QL_MEMORY_ALLOC_FAILED);
1751 	}
1752 
1753 	pkt->log.entry_type = LOG_TYPE;
1754 	pkt->log.entry_count = 1;
1755 	pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1756 	pkt->log.control_flags = (uint16_t)LE_16(flags);
1757 	pkt->log.port_id[0] = tq->d_id.b.al_pa;
1758 	pkt->log.port_id[1] = tq->d_id.b.area;
1759 	pkt->log.port_id[2] = tq->d_id.b.domain;
1760 	pkt->log.vp_index = ha->vp_index;
1761 
1762 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1763 	if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1764 		EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1765 		    pkt->log.entry_status, tq->d_id.b24);
1766 		rval = QL_FUNCTION_PARAMETER_ERROR;
1767 	}
1768 
1769 	if (rval == QL_SUCCESS) {
1770 		if (pkt->log.rsp_size == 0xB) {
1771 			LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1772 			tq->cmn_features = MSW(pkt->log.io_param[5]);
1773 			LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1774 			tq->conc_sequences = MSW(pkt->log.io_param[6]);
1775 			tq->relative_offset = LSW(pkt->log.io_param[6]);
1776 			LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1777 			tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1778 			tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1779 			LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1780 			tq->class3_open_sequences_per_exch =
1781 			    MSW(pkt->log.io_param[10]);
1782 			tq->prli_payload_length = 0x14;
1783 		}
1784 		if (mr != NULL) {
1785 			LITTLE_ENDIAN_16(&pkt->log.status);
1786 			LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1787 			LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1788 
1789 			if (pkt->log.status != CS_COMPLETE) {
1790 				EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1791 				    "%xh\n", pkt->log.status,
1792 				    pkt->log.io_param[0],
1793 				    pkt->log.io_param[1]);
1794 
1795 				switch (pkt->log.io_param[0]) {
1796 				case CS0_NO_LINK:
1797 				case CS0_FIRMWARE_NOT_READY:
1798 					mr->mb[0] = MBS_COMMAND_ERROR;
1799 					mr->mb[1] = 1;
1800 					break;
1801 				case CS0_NO_IOCB:
1802 				case CS0_NO_PCB_ALLOCATED:
1803 					mr->mb[0] = MBS_COMMAND_ERROR;
1804 					mr->mb[1] = 2;
1805 					break;
1806 				case CS0_NO_EXCH_CTRL_BLK:
1807 					mr->mb[0] = MBS_COMMAND_ERROR;
1808 					mr->mb[1] = 3;
1809 					break;
1810 				case CS0_COMMAND_FAILED:
1811 					mr->mb[0] = MBS_COMMAND_ERROR;
1812 					mr->mb[1] = 4;
1813 					switch (LSB(pkt->log.io_param[1])) {
1814 					case CS1_PLOGI_RESPONSE_FAILED:
1815 						mr->mb[2] = 3;
1816 						break;
1817 					case CS1_PRLI_FAILED:
1818 						mr->mb[2] = 4;
1819 						break;
1820 					case CS1_PRLI_RESPONSE_FAILED:
1821 						mr->mb[2] = 5;
1822 						break;
1823 					case CS1_COMMAND_LOGGED_OUT:
1824 						mr->mb[2] = 7;
1825 						break;
1826 					case CS1_PLOGI_FAILED:
1827 					default:
1828 						EL(ha, "log iop1 = %xh\n",
1829 						    LSB(pkt->log.io_param[1]))
1830 						mr->mb[2] = 2;
1831 						break;
1832 					}
1833 					break;
1834 				case CS0_PORT_NOT_LOGGED_IN:
1835 					mr->mb[0] = MBS_COMMAND_ERROR;
1836 					mr->mb[1] = 4;
1837 					mr->mb[2] = 7;
1838 					break;
1839 				case CS0_NO_FLOGI_ACC:
1840 				case CS0_NO_FABRIC_PRESENT:
1841 					mr->mb[0] = MBS_COMMAND_ERROR;
1842 					mr->mb[1] = 5;
1843 					break;
1844 				case CS0_ELS_REJECT_RECEIVED:
1845 					mr->mb[0] = MBS_COMMAND_ERROR;
1846 					mr->mb[1] = 0xd;
1847 					break;
1848 				case CS0_PORT_ID_USED:
1849 					mr->mb[0] = MBS_PORT_ID_USED;
1850 					mr->mb[1] = LSW(pkt->log.io_param[1]);
1851 					break;
1852 				case CS0_N_PORT_HANDLE_USED:
1853 					mr->mb[0] = MBS_LOOP_ID_USED;
1854 					mr->mb[1] = MSW(pkt->log.io_param[1]);
1855 					mr->mb[2] = LSW(pkt->log.io_param[1]);
1856 					break;
1857 				case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1858 					mr->mb[0] = MBS_ALL_IDS_IN_USE;
1859 					break;
1860 				case CS0_CMD_PARAMETER_ERROR:
1861 				default:
1862 					EL(ha, "pkt->log iop[0]=%xh\n",
1863 					    pkt->log.io_param[0]);
1864 					mr->mb[0] =
1865 					    MBS_COMMAND_PARAMETER_ERROR;
1866 					break;
1867 				}
1868 			} else {
1869 				QL_PRINT_3(ha, "status=%xh\n", pkt->log.status);
1870 
1871 				mr->mb[0] = MBS_COMMAND_COMPLETE;
1872 				mr->mb[1] = (uint16_t)
1873 				    (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1874 				if (pkt->log.io_param[0] & BIT_8) {
1875 					mr->mb[1] = (uint16_t)
1876 					    (mr->mb[1] | BIT_1);
1877 				}
1878 			}
1879 			rval = mr->mb[0];
1880 		}
1881 
1882 	}
1883 
1884 	kmem_free(pkt, pkt_size);
1885 
1886 	if (rval != QL_SUCCESS) {
1887 		EL(ha, "failed, rval=%xh, d_id=%xh loop_id=%xh\n",
1888 		    rval, tq->d_id.b24, loop_id);
1889 	} else {
1890 		/*EMPTY*/
1891 		QL_PRINT_3(ha, "done\n");
1892 	}
1893 
1894 	return (rval);
1895 }
1896 
1897 /*
1898  * ql_get_port_database
1899  *	Issue get port database mailbox command
1900  *	and copy context to device queue.
1901  *
1902  * Input:
1903  *	ha:	adapter state pointer.
1904  *	tq:	target queue pointer.
1905  *	opt:	options.
1906  *		PDF_NONE, PDF_PLOGI, PDF_ADISC
1907  * Returns:
1908  *	ql local function return status code.
1909  *
1910  * Context:
1911  *	Kernel context.
1912  */
1913 int
ql_get_port_database(ql_adapter_state_t * ha,ql_tgt_t * tq,uint8_t opt)1914 ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1915 {
1916 	int			rval;
1917 	dma_mem_t		mem_desc;
1918 	mbx_cmd_t		mc = {0};
1919 	mbx_cmd_t		*mcp = &mc;
1920 	port_database_23_t	*pd23;
1921 
1922 	QL_PRINT_3(ha, "started\n");
1923 
1924 	pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1925 	if (pd23 == NULL) {
1926 		rval = QL_MEMORY_ALLOC_FAILED;
1927 		EL(ha, "failed, rval = %xh\n", rval);
1928 		return (rval);
1929 	}
1930 
1931 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1932 	    PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1933 		return (QL_MEMORY_ALLOC_FAILED);
1934 	}
1935 
1936 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1937 		mcp->mb[0] = MBC_GET_PORT_DATABASE;
1938 		mcp->mb[1] = tq->loop_id;
1939 		mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1940 		mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1941 		mcp->mb[9] = ha->vp_index;
1942 		mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1943 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1944 		    MBX_2|MBX_1|MBX_0;
1945 	} else {
1946 		mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1947 		    MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1948 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1949 			mcp->mb[1] = tq->loop_id;
1950 			mcp->mb[10] = opt;
1951 			mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1952 			    MBX_2|MBX_1|MBX_0;
1953 		} else {
1954 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1955 			mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1956 		}
1957 	}
1958 
1959 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1960 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1961 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1962 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1963 	mcp->in_mb = MBX_0;
1964 	mcp->timeout = MAILBOX_TOV;
1965 	rval = ql_mailbox_command(ha, mcp);
1966 
1967 	if (rval == QL_SUCCESS) {
1968 		ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1969 	}
1970 
1971 	ql_free_dma_resource(ha, &mem_desc);
1972 
1973 	if (rval == QL_SUCCESS) {
1974 		if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1975 			port_database_24_t *pd24 = (port_database_24_t *)pd23;
1976 
1977 			tq->master_state = pd24->current_login_state;
1978 			tq->slave_state = pd24->last_stable_login_state;
1979 			if (PD_PORT_LOGIN(tq)) {
1980 				/* Names are big endian. */
1981 				bcopy((void *)&pd24->port_name[0],
1982 				    (void *)&tq->port_name[0], 8);
1983 				bcopy((void *)&pd24->node_name[0],
1984 				    (void *)&tq->node_name[0], 8);
1985 				tq->hard_addr.b.al_pa = pd24->hard_address[2];
1986 				tq->hard_addr.b.area = pd24->hard_address[1];
1987 				tq->hard_addr.b.domain = pd24->hard_address[0];
1988 				tq->class3_rcv_data_size =
1989 				    pd24->receive_data_size;
1990 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1991 				tq->prli_svc_param_word_0 =
1992 				    pd24->PRLI_service_parameter_word_0;
1993 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1994 				tq->prli_svc_param_word_3 =
1995 				    pd24->PRLI_service_parameter_word_3;
1996 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1997 			}
1998 		} else {
1999 			tq->master_state = pd23->master_state;
2000 			tq->slave_state = pd23->slave_state;
2001 			if (PD_PORT_LOGIN(tq)) {
2002 				/* Names are big endian. */
2003 				bcopy((void *)&pd23->port_name[0],
2004 				    (void *)&tq->port_name[0], 8);
2005 				bcopy((void *)&pd23->node_name[0],
2006 				    (void *)&tq->node_name[0], 8);
2007 				tq->hard_addr.b.al_pa = pd23->hard_address[2];
2008 				tq->hard_addr.b.area = pd23->hard_address[1];
2009 				tq->hard_addr.b.domain = pd23->hard_address[0];
2010 				tq->cmn_features = pd23->common_features;
2011 				LITTLE_ENDIAN_16(&tq->cmn_features);
2012 				tq->conc_sequences =
2013 				    pd23->total_concurrent_sequences;
2014 				LITTLE_ENDIAN_16(&tq->conc_sequences);
2015 				tq->relative_offset =
2016 				    pd23->RO_by_information_category;
2017 				LITTLE_ENDIAN_16(&tq->relative_offset);
2018 				tq->class3_recipient_ctl = pd23->recipient;
2019 				LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
2020 				tq->class3_rcv_data_size =
2021 				    pd23->receive_data_size;
2022 				LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
2023 				tq->class3_conc_sequences =
2024 				    pd23->concurrent_sequences;
2025 				LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
2026 				tq->class3_open_sequences_per_exch =
2027 				    pd23->open_sequences_per_exchange;
2028 				LITTLE_ENDIAN_16(
2029 				    &tq->class3_open_sequences_per_exch);
2030 				tq->prli_payload_length =
2031 				    pd23->PRLI_payload_length;
2032 				LITTLE_ENDIAN_16(&tq->prli_payload_length);
2033 				tq->prli_svc_param_word_0 =
2034 				    pd23->PRLI_service_parameter_word_0;
2035 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
2036 				tq->prli_svc_param_word_3 =
2037 				    pd23->PRLI_service_parameter_word_3;
2038 				LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
2039 			}
2040 		}
2041 
2042 		if (!PD_PORT_LOGIN(tq)) {
2043 			EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
2044 			    "master=%xh, slave=%xh\n", tq->d_id.b24,
2045 			    tq->loop_id, tq->master_state, tq->slave_state);
2046 			rval = QL_NOT_LOGGED_IN;
2047 		} else {
2048 			tq->flags = tq->prli_svc_param_word_3 &
2049 			    PRLI_W3_TARGET_FUNCTION ?
2050 			    tq->flags & ~TQF_INITIATOR_DEVICE :
2051 			    tq->flags | TQF_INITIATOR_DEVICE;
2052 
2053 			if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
2054 				tq->flags = tq->prli_svc_param_word_3 &
2055 				    PRLI_W3_RETRY ?
2056 				    tq->flags | TQF_TAPE_DEVICE :
2057 				    tq->flags & ~TQF_TAPE_DEVICE;
2058 			} else {
2059 				tq->flags &= ~TQF_TAPE_DEVICE;
2060 			}
2061 		}
2062 	}
2063 
2064 	kmem_free(pd23, PORT_DATABASE_SIZE);
2065 
2066 	/*
2067 	 * log the trace in any cases other than QL_SUCCESS.
2068 	 */
2069 	if (rval != QL_SUCCESS) {
2070 		EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n",
2071 		    rval, tq->d_id.b24, tq->loop_id);
2072 	} else {
2073 		/*EMPTY*/
2074 		QL_PRINT_3(ha, "done\n");
2075 	}
2076 
2077 	return (rval);
2078 }
2079 
2080 /*
2081  * ql_get_loop_position_map
2082  *	Issue get loop position map mailbox command.
2083  *
2084  * Input:
2085  *	ha:	adapter state pointer.
2086  *	size:	size of data buffer.
2087  *	bufp:	data pointer for DMA data.
2088  *
2089  * Returns:
2090  *	ql local function return status code.
2091  *
2092  * Context:
2093  *	Kernel context.
2094  */
2095 int
ql_get_loop_position_map(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2096 ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2097 {
2098 	int		rval;
2099 	dma_mem_t	mem_desc;
2100 	mbx_cmd_t	mc = {0};
2101 	mbx_cmd_t	*mcp = &mc;
2102 
2103 	QL_PRINT_3(ha, "started\n");
2104 
2105 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2106 	    (uint32_t)size)) != QL_SUCCESS) {
2107 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2108 		return (QL_MEMORY_ALLOC_FAILED);
2109 	}
2110 
2111 	mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2112 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2113 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2114 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2115 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2116 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2117 	mcp->in_mb = MBX_1|MBX_0;
2118 	mcp->timeout = MAILBOX_TOV;
2119 	rval = ql_mailbox_command(ha, mcp);
2120 
2121 	if (rval == QL_SUCCESS) {
2122 		ql_get_mbox_dma_data(&mem_desc, bufp);
2123 	}
2124 
2125 	ql_free_dma_resource(ha, &mem_desc);
2126 
2127 	if (rval != QL_SUCCESS) {
2128 		EL(ha, "failed=%xh\n", rval);
2129 	} else {
2130 		/*EMPTY*/
2131 		QL_PRINT_3(ha, "done\n");
2132 	}
2133 
2134 	return (rval);
2135 }
2136 
2137 /*
2138  * ql_set_rnid_params
2139  *	Issue set RNID parameters mailbox command.
2140  *
2141  * Input:
2142  *	ha:		adapter state pointer.
2143  *	size:		size of data buffer.
2144  *	bufp:		data pointer for DMA data.
2145  *
2146  * Returns:
2147  *	ql local function return status code.
2148  *
2149  * Context:
2150  *	Kernel context.
2151  */
2152 int
ql_set_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2153 ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2154 {
2155 	int		rval;
2156 	dma_mem_t	mem_desc;
2157 	mbx_cmd_t	mc = {0};
2158 	mbx_cmd_t	*mcp = &mc;
2159 
2160 	QL_PRINT_3(ha, "started\n");
2161 
2162 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2163 	    (uint32_t)size)) != QL_SUCCESS) {
2164 		EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2165 		return (rval);
2166 	}
2167 
2168 	mcp->mb[0] = MBC_SET_PARAMETERS;
2169 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2170 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2171 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2172 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2173 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2174 	mcp->in_mb = MBX_0;
2175 	mcp->timeout = MAILBOX_TOV;
2176 	rval = ql_mailbox_command(ha, mcp);
2177 
2178 	ql_free_dma_resource(ha, &mem_desc);
2179 
2180 	if (rval != QL_SUCCESS) {
2181 		EL(ha, "failed, rval = %xh\n", rval);
2182 	} else {
2183 		/*EMPTY*/
2184 		QL_PRINT_3(ha, "done\n");
2185 	}
2186 
2187 	return (rval);
2188 }
2189 
2190 /*
2191  * ql_send_rnid_els
2192  *	Issue a send node identfication data mailbox command.
2193  *
2194  * Input:
2195  *	ha:		adapter state pointer.
2196  *	loop_id:	FC loop id.
2197  *	opt:		options.
2198  *	size:		size of data buffer.
2199  *	bufp:		data pointer for DMA data.
2200  *
2201  * Returns:
2202  *	ql local function return status code.
2203  *
2204  * Context:
2205  *	Kernel context.
2206  */
2207 int
ql_send_rnid_els(ql_adapter_state_t * ha,uint16_t loop_id,uint8_t opt,size_t size,caddr_t bufp)2208 ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2209     size_t size, caddr_t bufp)
2210 {
2211 	int		rval;
2212 	dma_mem_t	mem_desc;
2213 	mbx_cmd_t	mc = {0};
2214 	mbx_cmd_t	*mcp = &mc;
2215 
2216 	QL_PRINT_3(ha, "started\n");
2217 
2218 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2219 	    (uint32_t)size)) != QL_SUCCESS) {
2220 		return (QL_MEMORY_ALLOC_FAILED);
2221 	}
2222 
2223 	mcp->mb[0] = MBC_SEND_RNID_ELS;
2224 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2225 		mcp->mb[1] = loop_id;
2226 		mcp->mb[9] = ha->vp_index;
2227 		mcp->mb[10] = opt;
2228 		mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2229 	} else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2230 		mcp->mb[1] = loop_id;
2231 		mcp->mb[10] = opt;
2232 		mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2233 	} else {
2234 		mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2235 		mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2236 	}
2237 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2238 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2239 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2240 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2241 	mcp->in_mb = MBX_0;
2242 	mcp->timeout = MAILBOX_TOV;
2243 	rval = ql_mailbox_command(ha, mcp);
2244 
2245 	if (rval == QL_SUCCESS) {
2246 		ql_get_mbox_dma_data(&mem_desc, bufp);
2247 	}
2248 
2249 	ql_free_dma_resource(ha, &mem_desc);
2250 
2251 	if (rval != QL_SUCCESS) {
2252 		EL(ha, "failed, rval = %xh\n", rval);
2253 	} else {
2254 		/*EMPTY*/
2255 		QL_PRINT_3(ha, "done\n");
2256 	}
2257 
2258 	return (rval);
2259 }
2260 
2261 /*
2262  * ql_get_rnid_params
2263  *	Issue get RNID parameters mailbox command.
2264  *
2265  * Input:
2266  *	ha:	adapter state pointer.
2267  *	size:	size of data buffer.
2268  *	bufp:	data pointer for DMA data.
2269  *
2270  * Returns:
2271  *	ql local function return status code.
2272  *
2273  * Context:
2274  *	Kernel context.
2275  */
2276 int
ql_get_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2277 ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2278 {
2279 	int		rval;
2280 	dma_mem_t	mem_desc;
2281 	mbx_cmd_t	mc = {0};
2282 	mbx_cmd_t	*mcp = &mc;
2283 
2284 	QL_PRINT_3(ha, "started\n");
2285 
2286 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2287 	    (uint32_t)size)) != QL_SUCCESS) {
2288 		return (QL_MEMORY_ALLOC_FAILED);
2289 	}
2290 
2291 	mcp->mb[0] = MBC_GET_PARAMETERS;
2292 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2293 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2294 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2295 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2296 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2297 	mcp->in_mb = MBX_0;
2298 	mcp->timeout = MAILBOX_TOV;
2299 	rval = ql_mailbox_command(ha, mcp);
2300 
2301 	if (rval == QL_SUCCESS) {
2302 		ql_get_mbox_dma_data(&mem_desc, bufp);
2303 	}
2304 
2305 	ql_free_dma_resource(ha, &mem_desc);
2306 
2307 	if (rval != QL_SUCCESS) {
2308 		EL(ha, "failed=%xh\n", rval);
2309 	} else {
2310 		/*EMPTY*/
2311 		QL_PRINT_3(ha, "done\n");
2312 	}
2313 
2314 	return (rval);
2315 }
2316 
2317 /*
2318  * ql_get_link_status
2319  *	Issue get link status mailbox command.
2320  *
2321  * Input:
2322  *	ha:		adapter state pointer.
2323  *	loop_id:	FC loop id or n_port_hdl.
2324  *	size:		size of data buffer.
2325  *	bufp:		data pointer for DMA data.
2326  *	port_no:	port number to query.
2327  *
2328  * Returns:
2329  *	ql local function return status code.
2330  *
2331  * Context:
2332  *	Kernel context.
2333  */
2334 int
ql_get_link_status(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2335 ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2336     caddr_t bufp, uint8_t port_no)
2337 {
2338 	dma_mem_t	mem_desc;
2339 	mbx_cmd_t	mc = {0};
2340 	mbx_cmd_t	*mcp = &mc;
2341 	int		rval = QL_SUCCESS;
2342 	int		retry = 0;
2343 
2344 	QL_PRINT_3(ha, "started\n");
2345 
2346 	do {
2347 		if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2348 		    (uint32_t)size)) != QL_SUCCESS) {
2349 			EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2350 			return (QL_MEMORY_ALLOC_FAILED);
2351 		}
2352 
2353 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2354 		if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2355 			if (loop_id == ha->loop_id) {
2356 				mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2357 				mcp->mb[8] = (uint16_t)(size >> 2);
2358 				mcp->out_mb = MBX_10|MBX_8;
2359 			} else {
2360 				mcp->mb[1] = loop_id;
2361 				mcp->mb[4] = port_no;
2362 				mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2363 				mcp->out_mb = MBX_10|MBX_4;
2364 			}
2365 		} else {
2366 			if (retry) {
2367 				port_no = (uint8_t)(port_no | BIT_3);
2368 			}
2369 			if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2370 				mcp->mb[1] = loop_id;
2371 				mcp->mb[10] = port_no;
2372 				mcp->out_mb = MBX_10;
2373 			} else {
2374 				mcp->mb[1] = (uint16_t)((loop_id << 8) |
2375 				    port_no);
2376 				mcp->out_mb = 0;
2377 			}
2378 		}
2379 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2380 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2381 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2382 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2383 		mcp->in_mb = MBX_1|MBX_0;
2384 		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2385 		mcp->timeout = MAILBOX_TOV;
2386 
2387 		rval = ql_mailbox_command(ha, mcp);
2388 
2389 		if (rval == QL_SUCCESS) {
2390 			ql_get_mbox_dma_data(&mem_desc, bufp);
2391 		}
2392 
2393 		ql_free_dma_resource(ha, &mem_desc);
2394 
2395 		if (rval != QL_SUCCESS) {
2396 			EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2397 		}
2398 
2399 		/*
2400 		 * Some of the devices want d_id in the payload,
2401 		 * strictly as per standard. Let's retry.
2402 		 */
2403 
2404 	} while (rval == QL_COMMAND_ERROR && !retry++);
2405 
2406 	if (rval != QL_SUCCESS) {
2407 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2408 	} else {
2409 		/*EMPTY*/
2410 		QL_PRINT_3(ha, "done\n");
2411 	}
2412 
2413 	return (rval);
2414 }
2415 
2416 /*
2417  * ql_get_status_counts
2418  *	Issue get adapter link status counts mailbox command.
2419  *
2420  * Input:
2421  *	ha:		adapter state pointer.
2422  *	loop_id:	FC loop id or n_port_hdl.
2423  *	size:		size of data buffer.
2424  *	bufp:		data pointer for DMA data.
2425  *	port_no:	port number to query.
2426  *
2427  * Returns:
2428  *	ql local function return status code.
2429  *
2430  * Context:
2431  *	Kernel context.
2432  */
2433 int
ql_get_status_counts(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2434 ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2435     caddr_t bufp, uint8_t port_no)
2436 {
2437 	dma_mem_t	mem_desc;
2438 	mbx_cmd_t	mc = {0};
2439 	mbx_cmd_t	*mcp = &mc;
2440 	int		rval = QL_SUCCESS;
2441 
2442 	QL_PRINT_3(ha, "started\n");
2443 
2444 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2445 	    (uint32_t)size)) != QL_SUCCESS) {
2446 		EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2447 		return (QL_MEMORY_ALLOC_FAILED);
2448 	}
2449 
2450 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2451 		mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2452 		mcp->mb[8] = (uint16_t)(size / 4);
2453 		mcp->out_mb = MBX_10|MBX_8;
2454 	} else {
2455 		mcp->mb[0] = MBC_GET_LINK_STATUS;
2456 
2457 		/* allows reporting when link is down */
2458 		if (CFG_IST(ha, CFG_CTRL_22XX) == 0) {
2459 			port_no = (uint8_t)(port_no | BIT_6);
2460 		}
2461 
2462 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2463 			mcp->mb[1] = loop_id;
2464 			mcp->mb[10] = port_no;
2465 			mcp->out_mb = MBX_10|MBX_1;
2466 		} else {
2467 			mcp->mb[1] = (uint16_t)((loop_id << 8) |
2468 			    port_no);
2469 			mcp->out_mb = MBX_1;
2470 		}
2471 	}
2472 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2473 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2474 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2475 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2476 	mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2477 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2478 	mcp->timeout = MAILBOX_TOV;
2479 	rval = ql_mailbox_command(ha, mcp);
2480 
2481 	if (rval == QL_SUCCESS) {
2482 		ql_get_mbox_dma_data(&mem_desc, bufp);
2483 	}
2484 
2485 	ql_free_dma_resource(ha, &mem_desc);
2486 
2487 	if (rval != QL_SUCCESS) {
2488 		EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2489 		    mcp->mb[1], mcp->mb[2]);
2490 	} else {
2491 		/*EMPTY*/
2492 		QL_PRINT_3(ha, "done\n");
2493 	}
2494 
2495 	return (rval);
2496 }
2497 
2498 /*
2499  * ql_reset_link_status
2500  *	Issue Reset Link Error Status mailbox command
2501  *
2502  * Input:
2503  *	ha:	adapter state pointer.
2504  *
2505  * Returns:
2506  *	ql local function return status code.
2507  *
2508  * Context:
2509  *	Kernel context.
2510  */
2511 int
ql_reset_link_status(ql_adapter_state_t * ha)2512 ql_reset_link_status(ql_adapter_state_t *ha)
2513 {
2514 	int		rval;
2515 	mbx_cmd_t	mc = {0};
2516 	mbx_cmd_t	*mcp = &mc;
2517 
2518 	QL_PRINT_3(ha, "started\n");
2519 
2520 	mcp->mb[0] = MBC_RESET_LINK_STATUS;
2521 	mcp->out_mb = MBX_0;
2522 	mcp->in_mb = MBX_0;
2523 	mcp->timeout = MAILBOX_TOV;
2524 	rval = ql_mailbox_command(ha, mcp);
2525 
2526 	if (rval != QL_SUCCESS) {
2527 		EL(ha, "failed=%xh\n", rval);
2528 	} else {
2529 		/*EMPTY*/
2530 		QL_PRINT_3(ha, "done\n");
2531 	}
2532 
2533 	return (rval);
2534 }
2535 
2536 /*
2537  * ql_loop_reset
2538  *	Issue loop reset.
2539  *
2540  * Input:
2541  *	ha:	adapter state pointer.
2542  *
2543  * Returns:
2544  *	ql local function return status code.
2545  *
2546  * Context:
2547  *	Kernel context.
2548  */
2549 int
ql_loop_reset(ql_adapter_state_t * ha)2550 ql_loop_reset(ql_adapter_state_t *ha)
2551 {
2552 	int	rval;
2553 
2554 	QL_PRINT_3(ha, "started\n");
2555 
2556 	if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2557 		rval = ql_lip_reset(ha, 0xff);
2558 	} else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2559 		rval = ql_full_login_lip(ha);
2560 	} else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2561 		rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2562 	} else {
2563 		rval = ql_initiate_lip(ha);
2564 	}
2565 
2566 	if (rval != QL_SUCCESS) {
2567 		EL(ha, "failed, rval = %xh\n", rval);
2568 	} else {
2569 		/*EMPTY*/
2570 		QL_PRINT_3(ha, "done\n");
2571 	}
2572 
2573 	return (rval);
2574 }
2575 
2576 /*
2577  * ql_initiate_lip
2578  *	Initiate LIP mailbox command.
2579  *
2580  * Input:
2581  *	ha:	adapter state pointer.
2582  *
2583  * Returns:
2584  *	ql local function return status code.
2585  *
2586  * Context:
2587  *	Kernel context.
2588  */
2589 int
ql_initiate_lip(ql_adapter_state_t * ha)2590 ql_initiate_lip(ql_adapter_state_t *ha)
2591 {
2592 	int		rval;
2593 	mbx_cmd_t	mc = {0};
2594 	mbx_cmd_t	*mcp = &mc;
2595 
2596 	QL_PRINT_3(ha, "started\n");
2597 
2598 	if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2599 		ql_toggle_loop_state(ha);
2600 		QL_PRINT_3(ha, "8081 done\n");
2601 		return (QL_SUCCESS);
2602 	}
2603 	if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2604 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2605 		mcp->mb[1] = BIT_4;
2606 		mcp->mb[3] = ha->loop_reset_delay;
2607 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2608 	} else {
2609 		mcp->mb[0] = MBC_INITIATE_LIP;
2610 		mcp->out_mb = MBX_0;
2611 	}
2612 	mcp->in_mb = MBX_0;
2613 	mcp->timeout = MAILBOX_TOV;
2614 	rval = ql_mailbox_command(ha, mcp);
2615 
2616 	if (rval != QL_SUCCESS) {
2617 		EL(ha, "failed, rval = %xh\n", rval);
2618 	} else {
2619 		/*EMPTY*/
2620 		QL_PRINT_3(ha, "done\n");
2621 	}
2622 
2623 	return (rval);
2624 }
2625 
2626 /*
2627  * ql_full_login_lip
2628  *	Issue full login LIP mailbox command.
2629  *
2630  * Input:
2631  *	ha:	adapter state pointer.
2632  *
2633  * Returns:
2634  *	ql local function return status code.
2635  *
2636  * Context:
2637  *	Kernel context.
2638  */
2639 int
ql_full_login_lip(ql_adapter_state_t * ha)2640 ql_full_login_lip(ql_adapter_state_t *ha)
2641 {
2642 	int		rval;
2643 	mbx_cmd_t	mc = {0};
2644 	mbx_cmd_t	*mcp = &mc;
2645 
2646 	QL_PRINT_3(ha, "started\n");
2647 
2648 	if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2649 		ql_toggle_loop_state(ha);
2650 		QL_PRINT_3(ha, "8081 done\n");
2651 		return (QL_SUCCESS);
2652 	}
2653 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2654 	if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2655 		mcp->mb[1] = BIT_3;
2656 	}
2657 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2658 	mcp->in_mb = MBX_0;
2659 	mcp->timeout = MAILBOX_TOV;
2660 	rval = ql_mailbox_command(ha, mcp);
2661 
2662 	if (rval != QL_SUCCESS) {
2663 		EL(ha, "failed, rval = %xh\n", rval);
2664 	} else {
2665 		/*EMPTY*/
2666 		QL_PRINT_3(ha, "done");
2667 	}
2668 
2669 	return (rval);
2670 }
2671 
2672 /*
2673  * ql_lip_reset
2674  *	Issue lip reset to a port.
2675  *
2676  * Input:
2677  *	ha:		adapter state pointer.
2678  *	loop_id:	FC loop id.
2679  *
2680  * Returns:
2681  *	ql local function return status code.
2682  *
2683  * Context:
2684  *	Kernel context.
2685  */
2686 int
ql_lip_reset(ql_adapter_state_t * ha,uint16_t loop_id)2687 ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2688 {
2689 	int		rval;
2690 	mbx_cmd_t	mc = {0};
2691 	mbx_cmd_t	*mcp = &mc;
2692 
2693 	QL_PRINT_3(ha, "started\n");
2694 
2695 	if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2696 		ql_toggle_loop_state(ha);
2697 		QL_PRINT_3(ha, "8081 done\n");
2698 		return (QL_SUCCESS);
2699 	}
2700 
2701 	if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2702 		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2703 		mcp->mb[1] = BIT_6;
2704 		mcp->mb[3] = ha->loop_reset_delay;
2705 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2706 	} else {
2707 		mcp->mb[0] = MBC_LIP_RESET;
2708 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2709 			mcp->mb[1] = loop_id;
2710 			mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2711 		} else {
2712 			mcp->mb[1] = (uint16_t)(loop_id << 8);
2713 			mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2714 		}
2715 		mcp->mb[2] = ha->loop_reset_delay;
2716 	}
2717 	mcp->in_mb = MBX_0;
2718 	mcp->timeout = MAILBOX_TOV;
2719 	rval = ql_mailbox_command(ha, mcp);
2720 
2721 	if (rval != QL_SUCCESS) {
2722 		EL(ha, "failed, rval = %xh\n", rval);
2723 	} else {
2724 		/*EMPTY*/
2725 		QL_PRINT_3(ha, "done\n");
2726 	}
2727 
2728 	return (rval);
2729 }
2730 
2731 /*
2732  * ql_abort_command
2733  *	Abort command aborts a specified IOCB.
2734  *
2735  * Input:
2736  *	ha:	adapter state pointer.
2737  *	sp:	SRB structure pointer.
2738  *
2739  * Returns:
2740  *	ql local function return status code.
2741  *
2742  * Context:
2743  *	Kernel context.
2744  */
2745 int
ql_abort_command(ql_adapter_state_t * ha,ql_srb_t * sp)2746 ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2747 {
2748 	int		rval;
2749 	mbx_cmd_t	mc = {0};
2750 	mbx_cmd_t	*mcp = &mc;
2751 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2752 
2753 	QL_PRINT_3(ha, "started\n");
2754 
2755 	sp->flags |= SRB_ABORTING;
2756 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2757 		rval = ql_abort_cmd_iocb(ha, sp);
2758 	} else {
2759 		mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2760 		if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2761 			mcp->mb[1] = tq->loop_id;
2762 		} else {
2763 			mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2764 		}
2765 		mcp->mb[2] = LSW(sp->handle);
2766 		mcp->mb[3] = MSW(sp->handle);
2767 		mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2768 		    sp->lun_queue->lun_no : 0);
2769 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2770 		mcp->in_mb = MBX_0;
2771 		mcp->timeout = MAILBOX_TOV;
2772 		rval = ql_mailbox_command(ha, mcp);
2773 	}
2774 
2775 	if (rval != QL_SUCCESS) {
2776 		EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2777 		    tq->d_id.b24, sp->handle);
2778 	} else {
2779 		/*EMPTY*/
2780 		QL_PRINT_3(ha, "done\n");
2781 	}
2782 
2783 	return (rval);
2784 }
2785 
2786 /*
2787  * ql_abort_cmd_iocb
2788  *	Function issues abort command IOCB.
2789  *
2790  * Input:
2791  *	ha:	adapter state pointer.
2792  *	sp:	SRB structure pointer.
2793  *
2794  * Returns:
2795  *	ql local function return status code.
2796  *
2797  * Context:
2798  *	Interrupt or Kernel context, no mailbox commands allowed.
2799  */
2800 static int
ql_abort_cmd_iocb(ql_adapter_state_t * ha,ql_srb_t * sp)2801 ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2802 {
2803 	ql_mbx_iocb_t	*pkt;
2804 	int		rval;
2805 	uint32_t	pkt_size;
2806 	uint16_t	comp_status;
2807 	ql_tgt_t	*tq = sp->lun_queue->target_queue;
2808 
2809 	QL_PRINT_3(ha, "started\n");
2810 
2811 	pkt_size = sizeof (ql_mbx_iocb_t);
2812 	if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2813 		EL(ha, "failed, kmem_zalloc\n");
2814 		return (QL_MEMORY_ALLOC_FAILED);
2815 	}
2816 
2817 	pkt->abo.entry_type = ABORT_CMD_TYPE;
2818 	pkt->abo.entry_count = 1;
2819 	pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2820 	if (!CFG_IST(ha, CFG_CTRL_82XX)) {
2821 		pkt->abo.options = AF_NO_ABTS;
2822 	}
2823 	pkt->abo.cmd_handle = LE_32(sp->handle);
2824 	pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2825 	pkt->abo.target_id[1] = tq->d_id.b.area;
2826 	pkt->abo.target_id[2] = tq->d_id.b.domain;
2827 	pkt->abo.vp_index = ha->vp_index;
2828 
2829 	rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2830 
2831 	if (rval == QL_SUCCESS) {
2832 		if ((pkt->abo.entry_status & 0x3c) != 0) {
2833 			EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2834 			    pkt->abo.entry_status, tq->d_id.b24);
2835 			rval = QL_FUNCTION_PARAMETER_ERROR;
2836 		} else {
2837 			comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2838 			if (comp_status != CS_COMPLETE) {
2839 				EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2840 				    comp_status, tq->d_id.b24);
2841 				rval = QL_FUNCTION_FAILED;
2842 			}
2843 		}
2844 	}
2845 
2846 	kmem_free(pkt, pkt_size);
2847 
2848 	if (rval != QL_SUCCESS) {
2849 		EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2850 	} else {
2851 		/*EMPTY*/
2852 		QL_PRINT_3(ha, "done\n");
2853 	}
2854 
2855 	return (rval);
2856 }
2857 
2858 /*
2859  * ql_verify_checksum
2860  *	Verify loaded RISC firmware.
2861  *
2862  * Input:
2863  *	ha = adapter state pointer.
2864  *
2865  * Returns:
2866  *	ql local function return status code.
2867  *
2868  * Context:
2869  *	Kernel context.
2870  */
2871 int
ql_verify_checksum(ql_adapter_state_t * ha)2872 ql_verify_checksum(ql_adapter_state_t *ha)
2873 {
2874 	int		rval;
2875 	mbx_cmd_t	mc = {0};
2876 	mbx_cmd_t	*mcp = &mc;
2877 
2878 	QL_PRINT_3(ha, "started\n");
2879 
2880 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2881 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2882 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2883 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2884 	} else {
2885 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2886 	}
2887 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
2888 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
2889 	mcp->timeout = MAILBOX_TOV;
2890 	rval = ql_mailbox_command(ha, mcp);
2891 
2892 	if (rval != QL_SUCCESS) {
2893 		EL(ha, "failed, rval = %xh\n", rval);
2894 	} else {
2895 		/*EMPTY*/
2896 		QL_PRINT_3(ha, "done\n");
2897 	}
2898 
2899 	return (rval);
2900 }
2901 
2902 /*
2903  * ql_get_id_list
2904  *	Get d_id and loop ID list.
2905  *
2906  * Input:
2907  *	ha:	adapter state pointer.
2908  *	bp:	data pointer for DMA data.
2909  *	size:	size of data buffer.
2910  *	mr:	pointer for mailbox data.
2911  *
2912  * Returns:
2913  *	ql local function return status code.
2914  *
2915  * Context:
2916  *	Kernel context.
2917  */
2918 int
ql_get_id_list(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,ql_mbx_data_t * mr)2919 ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2920     ql_mbx_data_t *mr)
2921 {
2922 	int		rval;
2923 	dma_mem_t	mem_desc;
2924 	mbx_cmd_t	mc = {0};
2925 	mbx_cmd_t	*mcp = &mc;
2926 
2927 	QL_PRINT_3(ha, "started\n");
2928 
2929 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2930 	    (uint32_t)size)) != QL_SUCCESS) {
2931 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2932 		return (QL_MEMORY_ALLOC_FAILED);
2933 	}
2934 
2935 	mcp->mb[0] = MBC_GET_ID_LIST;
2936 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2937 		mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2938 		mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2939 		mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2940 		mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2941 		mcp->mb[8] = (uint16_t)size;
2942 		mcp->mb[9] = ha->vp_index;
2943 		mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2944 	} else {
2945 		mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2946 		mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2947 		mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2948 		mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2949 		mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2950 	}
2951 	mcp->in_mb = MBX_1|MBX_0;
2952 	mcp->timeout = MAILBOX_TOV;
2953 	rval = ql_mailbox_command(ha, mcp);
2954 
2955 	if (rval == QL_SUCCESS) {
2956 		ql_get_mbox_dma_data(&mem_desc, bp);
2957 	}
2958 
2959 	ql_free_dma_resource(ha, &mem_desc);
2960 
2961 	/* Return mailbox data. */
2962 	if (mr != NULL) {
2963 		mr->mb[0] = mcp->mb[0];
2964 		mr->mb[1] = mcp->mb[1];
2965 	}
2966 
2967 	if (rval != QL_SUCCESS) {
2968 		EL(ha, "failed, rval = %xh\n", rval);
2969 	} else {
2970 		/*EMPTY*/
2971 		QL_PRINT_3(ha, "done\n");
2972 	}
2973 
2974 	return (rval);
2975 }
2976 
2977 /*
2978  * ql_wrt_risc_ram
2979  *	Load RISC RAM.
2980  *
2981  * Input:
2982  *	ha:		adapter state pointer.
2983  *	risc_address:	risc ram word address.
2984  *	bp:		DMA pointer.
2985  *	word_count:	16/32bit word count.
2986  *
2987  * Returns:
2988  *	ql local function return status code.
2989  *
2990  * Context:
2991  *	Kernel context.
2992  */
2993 int
ql_wrt_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)2994 ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2995     uint32_t word_count)
2996 {
2997 	int		rval;
2998 	mbx_cmd_t	mc = {0};
2999 	mbx_cmd_t	*mcp = &mc;
3000 
3001 	QL_PRINT_3(ha, "started\n");
3002 
3003 	mcp->mb[1] = LSW(risc_address);
3004 	mcp->mb[2] = MSW(LSD(bp));
3005 	mcp->mb[3] = LSW(LSD(bp));
3006 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3007 		mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
3008 		mcp->mb[4] = MSW(word_count);
3009 		mcp->mb[5] = LSW(word_count);
3010 		mcp->mb[8] = MSW(risc_address);
3011 		mcp->out_mb = MBX_0_THRU_8;
3012 	} else {
3013 		mcp->mb[0] = MBC_LOAD_RISC_RAM;
3014 		mcp->mb[4] = LSW(word_count);
3015 		mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3016 	}
3017 	mcp->mb[6] = MSW(MSD(bp));
3018 	mcp->mb[7] = LSW(MSD(bp));
3019 	mcp->in_mb = MBX_0;
3020 	mcp->timeout = MAILBOX_TOV;
3021 	rval = ql_mailbox_command(ha, mcp);
3022 
3023 	if (rval != QL_SUCCESS) {
3024 		EL(ha, "failed, rval = %xh\n", rval);
3025 	} else {
3026 		/*EMPTY*/
3027 		QL_PRINT_3(ha, "done\n");
3028 	}
3029 
3030 	return (rval);
3031 }
3032 
3033 /*
3034  * ql_rd_risc_ram
3035  *	Get RISC RAM.
3036  *
3037  * Input:
3038  *	ha:		adapter state pointer.
3039  *	risc_address:	risc ram word address.
3040  *	bp:		direct data pointer.
3041  *	word_count:	16/32bit word count.
3042  *
3043  * Returns:
3044  *	ql local function return status code.
3045  *
3046  * Context:
3047  *	Kernel context.
3048  */
3049 int
ql_rd_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)3050 ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
3051     uint32_t word_count)
3052 {
3053 	int		rval;
3054 	mbx_cmd_t	mc = {0};
3055 	mbx_cmd_t	*mcp = &mc;
3056 
3057 	QL_PRINT_3(ha, "started\n");
3058 
3059 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3060 		mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
3061 		mcp->mb[1] = LSW(risc_address);
3062 		mcp->mb[2] = MSW(LSD(bp));
3063 		mcp->mb[3] = LSW(LSD(bp));
3064 		mcp->mb[4] = MSW(word_count);
3065 		mcp->mb[5] = LSW(word_count);
3066 		mcp->mb[6] = MSW(MSD(bp));
3067 		mcp->mb[7] = LSW(MSD(bp));
3068 		mcp->mb[8] = MSW(risc_address);
3069 		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
3070 		    MBX_0;
3071 	} else {
3072 		mcp->mb[0] = MBC_DUMP_RAM;	/* doesn't support 64bit addr */
3073 		mcp->mb[1] = LSW(risc_address);
3074 		mcp->mb[2] = MSW(LSD(bp));
3075 		mcp->mb[3] = LSW(LSD(bp));
3076 		mcp->mb[4] = LSW(word_count);
3077 		mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3078 	}
3079 	mcp->in_mb = MBX_0;
3080 	mcp->timeout = MAILBOX_TOV;
3081 	rval = ql_mailbox_command(ha, mcp);
3082 
3083 	if (rval != QL_SUCCESS) {
3084 		EL(ha, "failed, rval = %xh\n", rval);
3085 	} else {
3086 		/*EMPTY*/
3087 		QL_PRINT_3(ha, "done\n");
3088 	}
3089 
3090 	return (rval);
3091 }
3092 
3093 /*
3094  * ql_wrt_risc_ram_word
3095  *	Write RISC RAM word.
3096  *
3097  * Input:
3098  *	ha:		adapter state pointer.
3099  *	risc_address:	risc ram word address.
3100  *	data:		data.
3101  *
3102  * Returns:
3103  *	ql local function return status code.
3104  *
3105  * Context:
3106  *	Kernel context.
3107  */
3108 int
ql_wrt_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t data)3109 ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3110     uint32_t data)
3111 {
3112 	int		rval;
3113 	mbx_cmd_t	mc = {0};
3114 	mbx_cmd_t	*mcp = &mc;
3115 
3116 	QL_PRINT_3(ha, "started\n");
3117 
3118 	mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3119 	mcp->mb[1] = LSW(risc_address);
3120 	mcp->mb[2] = LSW(data);
3121 	mcp->mb[3] = MSW(data);
3122 	mcp->mb[8] = MSW(risc_address);
3123 	mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3124 	mcp->in_mb = MBX_0;
3125 	mcp->timeout = MAILBOX_TOV;
3126 
3127 	rval = ql_mailbox_command(ha, mcp);
3128 
3129 	if (rval != QL_SUCCESS) {
3130 		EL(ha, "failed, rval = %xh\n", rval);
3131 	} else {
3132 		/*EMPTY*/
3133 		QL_PRINT_3(ha, "done\n");
3134 	}
3135 
3136 	return (rval);
3137 }
3138 
3139 /*
3140  * ql_rd_risc_ram_word
3141  *	Read RISC RAM word.
3142  *
3143  * Input:
3144  *	ha:		adapter state pointer.
3145  *	risc_address:	risc ram word address.
3146  *	data:		data pointer.
3147  *
3148  * Returns:
3149  *	ql local function return status code.
3150  *
3151  * Context:
3152  *	Kernel context.
3153  */
3154 int
ql_rd_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t * data)3155 ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3156     uint32_t *data)
3157 {
3158 	int		rval;
3159 	mbx_cmd_t	mc = {0};
3160 	mbx_cmd_t	*mcp = &mc;
3161 
3162 	QL_PRINT_3(ha, "started\n");
3163 
3164 	mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3165 	mcp->mb[1] = LSW(risc_address);
3166 	mcp->mb[8] = MSW(risc_address);
3167 	mcp->out_mb = MBX_8|MBX_1|MBX_0;
3168 	mcp->in_mb = MBX_3|MBX_2|MBX_0;
3169 	mcp->timeout = MAILBOX_TOV;
3170 
3171 	rval = ql_mailbox_command(ha, mcp);
3172 
3173 	if (rval != QL_SUCCESS) {
3174 		EL(ha, "failed, rval = %xh\n", rval);
3175 	} else {
3176 		*data = mcp->mb[2];
3177 		if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3178 			*data |= mcp->mb[3] << 16;
3179 		}
3180 		QL_PRINT_3(ha, "done\n");
3181 	}
3182 
3183 	return (rval);
3184 }
3185 
3186 /*
3187  * ql_issue_mbx_iocb
3188  *	Issue IOCB using mailbox command
3189  *
3190  * Input:
3191  *	ha:	adapter state pointer.
3192  *	bp:	buffer pointer.
3193  *	size:	buffer size.
3194  *
3195  * Returns:
3196  *	ql local function return status code.
3197  *
3198  * Context:
3199  *	Kernel context.
3200  */
3201 int
ql_issue_mbx_iocb(ql_adapter_state_t * ha,caddr_t bp,uint32_t size)3202 ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3203 {
3204 	int		rval;
3205 	dma_mem_t	mem_desc;
3206 	mbx_cmd_t	mc = {0};
3207 	mbx_cmd_t	*mcp = &mc;
3208 
3209 	QL_PRINT_3(ha, "started\n");
3210 
3211 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3212 	    QL_SUCCESS) {
3213 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3214 		return (rval);
3215 	}
3216 
3217 	mcp->mb[0] = MBC_EXECUTE_IOCB;
3218 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3219 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3220 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3221 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3222 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3223 	mcp->in_mb = MBX_1|MBX_0;
3224 	mcp->timeout = MAILBOX_TOV + 5;
3225 	rval = ql_mailbox_command(ha, mcp);
3226 
3227 	if (rval == QL_SUCCESS) {
3228 		ql_get_mbox_dma_data(&mem_desc, bp);
3229 	}
3230 
3231 	ql_free_dma_resource(ha, &mem_desc);
3232 
3233 	if (rval != QL_SUCCESS) {
3234 		EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3235 	} else {
3236 		/*EMPTY*/
3237 		QL_PRINT_3(ha, "done\n");
3238 	}
3239 
3240 	return (rval);
3241 }
3242 
3243 /*
3244  * ql_mbx_wrap_test
3245  *	Mailbox register wrap test.
3246  *
3247  * Input:
3248  *	ha:	adapter state pointer.
3249  *	mr:	pointer for in/out mailbox data.
3250  *
3251  * Returns:
3252  *	ql local function return status code.
3253  *
3254  * Context:
3255  *	Kernel context.
3256  */
3257 int
ql_mbx_wrap_test(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3258 ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3259 {
3260 	int		rval;
3261 	mbx_cmd_t	mc = {0};
3262 	mbx_cmd_t	*mcp = &mc;
3263 
3264 	QL_PRINT_3(ha, "started cfg=0x%llx\n", ha->cfg_flags);
3265 
3266 	mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3267 	if (mr == NULL) {
3268 		mcp->mb[1] = 0xAAAA;
3269 		mcp->mb[2] = 0x5555;
3270 		mcp->mb[3] = 0xAA55;
3271 		mcp->mb[4] = 0x55AA;
3272 		mcp->mb[5] = 0xA5A5;
3273 		mcp->mb[6] = 0x5A5A;
3274 		mcp->mb[7] = 0x2525;
3275 	} else {
3276 		mcp->mb[1] = mr->mb[1];
3277 		mcp->mb[2] = mr->mb[2];
3278 		mcp->mb[3] = mr->mb[3];
3279 		mcp->mb[4] = mr->mb[4];
3280 		mcp->mb[5] = mr->mb[5];
3281 		mcp->mb[6] = mr->mb[6];
3282 		mcp->mb[7] = mr->mb[7];
3283 	}
3284 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3285 	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3286 	mcp->timeout = MAILBOX_TOV;
3287 	rval = ql_mailbox_command(ha, mcp);
3288 	if (rval == QL_SUCCESS) {
3289 		if (mr == NULL) {
3290 			if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
3291 			    mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) {
3292 				rval = QL_FUNCTION_FAILED;
3293 			}
3294 			if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
3295 			    mcp->mb[7] != 0x2525) {
3296 				rval = QL_FUNCTION_FAILED;
3297 			}
3298 		} else {
3299 			if (mcp->mb[1] != mr->mb[1] ||
3300 			    mcp->mb[2] != mr->mb[2] ||
3301 			    mcp->mb[3] != mr->mb[3] ||
3302 			    mcp->mb[4] != mr->mb[4]) {
3303 				rval = QL_FUNCTION_FAILED;
3304 			}
3305 			if (mcp->mb[5] != mr->mb[5] ||
3306 			    mcp->mb[6] != mr->mb[6] ||
3307 			    mcp->mb[7] != mr->mb[7]) {
3308 				rval = QL_FUNCTION_FAILED;
3309 			}
3310 		}
3311 	}
3312 
3313 	if (rval != QL_SUCCESS) {
3314 		EL(ha, "failed=%xh\n", rval);
3315 	} else {
3316 		/*EMPTY*/
3317 		QL_PRINT_3(ha, "done\n");
3318 	}
3319 
3320 	return (rval);
3321 }
3322 
3323 /*
3324  * ql_execute_fw
3325  *	Start adapter firmware.
3326  *
3327  * Input:
3328  *	ha:	adapter state pointer.
3329  *
3330  * Returns:
3331  *	ql local function return status code.
3332  *
3333  * Context:
3334  *	Kernel context.
3335  */
3336 int
ql_execute_fw(ql_adapter_state_t * ha)3337 ql_execute_fw(ql_adapter_state_t *ha)
3338 {
3339 	int		rval;
3340 	mbx_cmd_t	mc = {0};
3341 	mbx_cmd_t	*mcp = &mc;
3342 
3343 	QL_PRINT_3(ha, "started\n");
3344 
3345 	if (CFG_IST(ha, CFG_CTRL_82XX)) {
3346 		return (QL_SUCCESS);
3347 	}
3348 
3349 	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3350 	if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3351 		mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3352 		mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3353 	} else {
3354 		mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3355 	}
3356 	if (CFG_IST(ha, CFG_LR_SUPPORT)) {
3357 		mcp->mb[4] = BIT_0;
3358 	}
3359 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3360 	mcp->in_mb = MBX_0;
3361 	mcp->timeout = MAILBOX_TOV;
3362 	rval = ql_mailbox_command(ha, mcp);
3363 
3364 	if (CFG_IST(ha, CFG_CTRL_22XX)) {
3365 		rval = QL_SUCCESS;
3366 	}
3367 
3368 	if (rval != QL_SUCCESS) {
3369 		EL(ha, "failed=%xh\n", rval);
3370 	} else {
3371 		/*EMPTY*/
3372 		QL_PRINT_3(ha, "done\n");
3373 	}
3374 
3375 	return (rval);
3376 }
3377 
3378 /*
3379  * ql_get_firmware_option
3380  *	 Get Firmware Options Mailbox Command.
3381  *
3382  * Input:
3383  *	ha:	adapter state pointer.
3384  *	mr:	pointer for mailbox data.
3385  *
3386  * Returns:
3387  *	ql local function return status code.
3388  *
3389  * Context:
3390  *	Kernel context.
3391  */
3392 int
ql_get_firmware_option(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3393 ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3394 {
3395 	int		rval;
3396 	mbx_cmd_t	mc = {0};
3397 	mbx_cmd_t	*mcp = &mc;
3398 
3399 	QL_PRINT_3(ha, "started\n");
3400 
3401 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3402 	mcp->out_mb = MBX_0;
3403 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3404 	mcp->timeout = MAILBOX_TOV;
3405 	rval = ql_mailbox_command(ha, mcp);
3406 
3407 	/* Return mailbox data. */
3408 	if (mr != NULL) {
3409 		mr->mb[0] = mcp->mb[0];
3410 		mr->mb[1] = mcp->mb[1];
3411 		mr->mb[2] = mcp->mb[2];
3412 		mr->mb[3] = mcp->mb[3];
3413 	}
3414 
3415 	if (rval != QL_SUCCESS) {
3416 		EL(ha, "failed=%xh\n", rval);
3417 	} else {
3418 		/*EMPTY*/
3419 		QL_PRINT_9(ha, "done\n");
3420 	}
3421 
3422 	return (rval);
3423 }
3424 
3425 /*
3426  * ql_set_firmware_option
3427  *	 Set Firmware Options Mailbox Command.
3428  *
3429  * Input:
3430  *	ha:	adapter state pointer.
3431  *	mr:	pointer for mailbox data.
3432  *
3433  * Returns:
3434  *	ql local function return status code.
3435  *
3436  * Context:
3437  *	Kernel context.
3438  */
3439 int
ql_set_firmware_option(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3440 ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3441 {
3442 	int		rval;
3443 	mbx_cmd_t	mc = {0};
3444 	mbx_cmd_t	*mcp = &mc;
3445 
3446 	QL_PRINT_3(ha, "started\n");
3447 
3448 	if (mr != NULL) {
3449 		mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3450 		mcp->mb[1] = mr->mb[1];
3451 		mcp->mb[2] = mr->mb[2];
3452 		mcp->mb[3] = mr->mb[3];
3453 		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3454 		mcp->in_mb = MBX_0;
3455 		mcp->timeout = MAILBOX_TOV;
3456 		rval = ql_mailbox_command(ha, mcp);
3457 	} else {
3458 		rval = QL_FUNCTION_PARAMETER_ERROR;
3459 	}
3460 
3461 	if (rval != QL_SUCCESS) {
3462 		EL(ha, "failed=%xh\n", rval);
3463 	} else {
3464 		/*EMPTY*/
3465 		QL_PRINT_3(ha, "done\n");
3466 	}
3467 
3468 	return (rval);
3469 }
3470 
3471 /*
3472  * ql_init_firmware
3473  *	 Initialize firmware mailbox command.
3474  *
3475  * Input:
3476  *	ha:	adapter state pointer.
3477  *	ha->init_ctrl_blk = setup for transmit.
3478  *
3479  * Returns:
3480  *	ql local function return status code.
3481  *
3482  * Context:
3483  *	Kernel context.
3484  */
3485 int
ql_init_firmware(ql_adapter_state_t * ha)3486 ql_init_firmware(ql_adapter_state_t *ha)
3487 {
3488 	int		rval;
3489 	dma_mem_t	mem_desc;
3490 	mbx_cmd_t	mc = {0};
3491 	mbx_cmd_t	*mcp = &mc;
3492 
3493 	QL_PRINT_3(ha, "started\n");
3494 
3495 	if (ha->flags & MULTI_QUEUE) {
3496 		WR32_MBAR_REG(ha, ha->req_q[0]->mbar_req_in, 0);
3497 		WR32_MBAR_REG(ha, ha->rsp_queues[0]->mbar_rsp_out, 0);
3498 	} else if (CFG_IST(ha, CFG_CTRL_82XX)) {
3499 		ql_8021_wr_req_in(ha, 0);
3500 		WRT32_IO_REG(ha, req_out, 0);
3501 		WRT32_IO_REG(ha, resp_in, 0);
3502 		WRT32_IO_REG(ha, resp_out, 0);
3503 	} else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3504 		WRT32_IO_REG(ha, req_in, 0);
3505 		WRT32_IO_REG(ha, resp_out, 0);
3506 		WRT32_IO_REG(ha, pri_req_in, 0);
3507 		WRT32_IO_REG(ha, atio_req_out, 0);
3508 	} else {
3509 		WRT16_IO_REG(ha, req_in, 0);
3510 		WRT16_IO_REG(ha, resp_out, 0);
3511 	}
3512 	if (ha->req_q[0]->req_out_shadow_ptr) {
3513 		*ha->req_q[0]->req_out_shadow_ptr = 0;
3514 	}
3515 	if (ha->rsp_queues[0]->rsp_in_shadow_ptr) {
3516 		*ha->rsp_queues[0]->rsp_in_shadow_ptr = 0;
3517 	}
3518 
3519 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3520 	    (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3521 	    QL_SUCCESS) {
3522 		EL(ha, "dma setup failed=%xh\n", rval);
3523 		return (rval);
3524 	}
3525 
3526 	mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3527 	    MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3528 
3529 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
3530 		mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_22XX) ?
3531 		    0x204c : 0x52);
3532 	}
3533 
3534 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3535 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3536 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3537 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3538 	if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
3539 		uint64_t		ofst, addr;
3540 		ql_init_24xx_cb_t	*icb = (ql_init_24xx_cb_t *)
3541 		    &ha->init_ctrl_blk.cb24;
3542 
3543 		mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW;
3544 		if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) {
3545 			ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb;
3546 			addr = mem_desc.cookie.dmac_laddress + ofst;
3547 			mcp->mb[10] = MSW(LSD(addr));
3548 			mcp->mb[11] = LSW(LSD(addr));
3549 			mcp->mb[12] = MSW(MSD(addr));
3550 			mcp->mb[13] = LSW(MSD(addr));
3551 			mcp->mb[14] = sizeof (ql_ext_icb_8100_t);
3552 			mcp->mb[1] = BIT_0;
3553 		}
3554 		mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
3555 		    MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3556 	} else {
3557 		mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3558 	}
3559 	mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0;
3560 	mcp->timeout = MAILBOX_TOV;
3561 	rval = ql_mailbox_command(ha, mcp);
3562 
3563 	if (rval == QL_SUCCESS) {
3564 		ha->sfp_stat = mcp->mb[2];
3565 		if (CFG_IST(ha, CFG_CTRL_82XX)) {
3566 			(void) ql_8021_get_md_template(ha);
3567 		} else {
3568 			uint16_t	i, opt;
3569 
3570 			opt = ha->flags & NO_INTR_HANDSHAKE ?
3571 			    IMO_NONE : IMO_INTERRUPT_HANDSHAKE;
3572 			if (ha->flags & QUEUE_SHADOW_PTRS) {
3573 				opt |= IMO_QUEUE_POINTER_SHADOWING;
3574 			}
3575 			/* Initialize ha multi-response-queue request queue */
3576 			if (ha->rsp_queues_cnt > 1) {
3577 				rval = ql_init_req_q(ha, ha->req_q[1], opt);
3578 				if (rval != QL_SUCCESS) {
3579 					EL(ha, "ql_init_req_q=%xh\n", rval);
3580 					return (rval);
3581 				}
3582 			}
3583 			/* Initialize multi-response queues */
3584 			for (i = 1; i < ha->rsp_queues_cnt; i++) {
3585 				rval = ql_init_rsp_q(ha, ha->rsp_queues[i],
3586 				    opt);
3587 				if (rval != QL_SUCCESS) {
3588 					EL(ha, "ql_init_rsp_q=%xh\n", rval);
3589 					return (rval);
3590 				}
3591 			}
3592 		}
3593 	}
3594 	ql_free_dma_resource(ha, &mem_desc);
3595 
3596 	if (rval != QL_SUCCESS) {
3597 		EL(ha, "failed=%xh\n", rval);
3598 	} else {
3599 		/*EMPTY*/
3600 		QL_PRINT_3(ha, "done\n");
3601 	}
3602 
3603 	return (rval);
3604 }
3605 
3606 /*
3607  * ql_get_firmware_state
3608  *	Get adapter firmware state.
3609  *
3610  * Input:
3611  *	ha:	adapter state pointer.
3612  *	mr:	pointer for mailbox data.
3613  *
3614  * Returns:
3615  *	ql local function return status code.
3616  *
3617  * Context:
3618  *	Kernel context.
3619  */
3620 int
ql_get_firmware_state(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3621 ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3622 {
3623 	int		rval;
3624 	mbx_cmd_t	mc = {0};
3625 	mbx_cmd_t	*mcp = &mc;
3626 
3627 	QL_PRINT_3(ha, "started\n");
3628 
3629 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3630 	mcp->out_mb = MBX_0;
3631 	mcp->in_mb = MBX_0_THRU_6;
3632 	mcp->timeout = MAILBOX_TOV;
3633 	rval = ql_mailbox_command(ha, mcp);
3634 
3635 	ha->fw_state[0] = mcp->mb[0];
3636 	ha->fw_state[1] = mcp->mb[1];
3637 	ha->fw_state[2] = mcp->mb[2];
3638 	ha->fw_state[3] = mcp->mb[3];
3639 	ha->fw_state[4] = mcp->mb[4];
3640 	ha->fw_state[5] = mcp->mb[5];
3641 	ha->fw_state[6] = mcp->mb[6];
3642 
3643 	/* Return mailbox data. */
3644 	if (mr != NULL) {
3645 		mr->mb[1] = mcp->mb[1];
3646 		mr->mb[2] = mcp->mb[2];
3647 		mr->mb[3] = mcp->mb[3];
3648 		mr->mb[4] = mcp->mb[4];
3649 		mr->mb[5] = mcp->mb[5];
3650 		mr->mb[6] = mcp->mb[6];
3651 	}
3652 
3653 	ha->sfp_stat = mcp->mb[2];
3654 
3655 	if (rval != QL_SUCCESS) {
3656 		EL(ha, "failed=%xh\n", rval);
3657 	} else {
3658 		/*EMPTY*/
3659 		QL_PRINT_3(ha, "done\n");
3660 	}
3661 
3662 	return (rval);
3663 }
3664 
3665 /*
3666  * ql_get_adapter_id
3667  *	Get adapter ID and topology.
3668  *
3669  * Input:
3670  *	ha:	adapter state pointer.
3671  *	mr:	pointer for mailbox data.
3672  *
3673  * Returns:
3674  *	ql local function return status code.
3675  *
3676  * Context:
3677  *	Kernel context.
3678  */
3679 int
ql_get_adapter_id(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3680 ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3681 {
3682 	int		i, rval;
3683 	mbx_cmd_t	mc = {0};
3684 	mbx_cmd_t	*mcp = &mc;
3685 
3686 	QL_PRINT_3(ha, "started\n");
3687 
3688 	mcp->mb[0] = MBC_GET_ID;
3689 	if (ha->flags & VP_ENABLED) {
3690 		mcp->mb[9] = ha->vp_index;
3691 	}
3692 	mcp->out_mb = MBX_9|MBX_0;
3693 	mcp->in_mb = MBX_0_THRU_19;
3694 	mcp->timeout = MAILBOX_TOV;
3695 
3696 	rval = ql_mailbox_command(ha, mcp);
3697 
3698 	/* Return mailbox data. */
3699 	if (mr != NULL) {
3700 		for (i = 0; i < 20; i++) {
3701 			mr->mb[i] = mcp->mb[i];
3702 		}
3703 	}
3704 
3705 	if (rval != QL_SUCCESS) {
3706 		EL(ha, "failed=%xh\n", rval);
3707 	} else {
3708 		/*EMPTY*/
3709 		QL_PRINT_3(ha, "done\n");
3710 	}
3711 
3712 	return (rval);
3713 }
3714 
3715 /*
3716  * ql_get_fw_version
3717  *	Get firmware version.
3718  *
3719  * Input:
3720  *	ha:	adapter state pointer.
3721  *	mr:	pointer for mailbox data.
3722  *
3723  * Returns:
3724  *	ql local function return status code.
3725  *
3726  * Context:
3727  *	Kernel context.
3728  */
3729 int
ql_get_fw_version(ql_adapter_state_t * ha,ql_mbx_data_t * mr,uint16_t timeout)3730 ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout)
3731 {
3732 	int		rval, i;
3733 	mbx_cmd_t	mc = {0};
3734 	mbx_cmd_t	*mcp = &mc;
3735 
3736 	QL_PRINT_3(ha, "started\n");
3737 
3738 	mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3739 	mcp->out_mb = MBX_0;
3740 	if (CFG_IST(ha, CFG_CTRL_83XX)) {
3741 		mcp->in_mb = MBX_0_THRU_17;
3742 	} else if (CFG_IST(ha, CFG_CTRL_27XX)) {
3743 		mcp->in_mb = MBX_0_THRU_25;
3744 	} else {
3745 		mcp->in_mb = MBX_0_THRU_13;
3746 	}
3747 	mcp->timeout = timeout;
3748 	rval = ql_mailbox_command(ha, mcp);
3749 
3750 	/* Return mailbox data. */
3751 	if (mr != NULL) {
3752 		for (i = 0; i < ha->reg_off->mbox_cnt && mcp->in_mb; i++) {
3753 			if (mcp->in_mb & MBX_0) {
3754 				mr->mb[i] = mcp->mb[i];
3755 			}
3756 			mcp->in_mb >>= 1;
3757 		}
3758 	}
3759 
3760 	if (rval != QL_SUCCESS) {
3761 		EL(ha, "failed=%xh\n", rval);
3762 	} else {
3763 		/*EMPTY*/
3764 		QL_PRINT_3(ha, "done\n");
3765 	}
3766 
3767 	return (rval);
3768 }
3769 
3770 /*
3771  * ql_data_rate
3772  *	 Issue data rate Mailbox Command.
3773  *
3774  * Input:
3775  *	ha:	adapter state pointer.
3776  *	mr:	pointer for mailbox data.
3777  *
3778  * Returns:
3779  *	ql local function return status code.
3780  *
3781  * Context:
3782  *	Kernel context.
3783  */
3784 int
ql_data_rate(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3785 ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3786 {
3787 	int		rval;
3788 	mbx_cmd_t	mc = {0};
3789 	mbx_cmd_t	*mcp = &mc;
3790 
3791 	QL_PRINT_3(ha, "started\n");
3792 
3793 	if (mr != NULL) {
3794 		mcp->mb[0] = MBC_DATA_RATE;
3795 		mcp->mb[1] = mr->mb[1];
3796 		mcp->mb[2] = mr->mb[2];
3797 		mcp->out_mb = MBX_2|MBX_1|MBX_0;
3798 		mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3799 		mcp->timeout = MAILBOX_TOV;
3800 		rval = ql_mailbox_command(ha, mcp);
3801 
3802 		/* Return mailbox data. */
3803 		mr->mb[1] = mcp->mb[1];
3804 		mr->mb[2] = mcp->mb[2];
3805 		mr->mb[3] = mcp->mb[3];
3806 	} else {
3807 		rval = QL_FUNCTION_PARAMETER_ERROR;
3808 	}
3809 
3810 	ha->sfp_stat = mcp->mb[2];
3811 
3812 	if (rval != QL_SUCCESS) {
3813 		EL(ha, "failed=%xh\n", rval);
3814 	} else {
3815 		/*EMPTY*/
3816 		QL_PRINT_3(ha, "done\n");
3817 	}
3818 
3819 	return (rval);
3820 }
3821 
3822 /*
3823  * ql_Diag_Loopback
3824  *	Issue Reset Link Status mailbox command
3825  *
3826  * Input:
3827  *	ha:	adapter state pointer.
3828  *	bp:	buffer pointer.
3829  *	size:	buffer size.
3830  *	opt:	command options.
3831  *	it_cnt:	iteration count.
3832  *	mr:	pointer for mailbox data.
3833  *
3834  * Returns:
3835  *	ql local function return status code.
3836  *
3837  * Context:
3838  *	Kernel context.
3839  */
3840 int
ql_diag_loopback(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,uint16_t opt,uint32_t it_cnt,ql_mbx_data_t * mr)3841 ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
3842     uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3843 {
3844 	int		rval;
3845 	dma_mem_t	mem_desc;
3846 	mbx_cmd_t	mc = {0};
3847 	mbx_cmd_t	*mcp = &mc;
3848 
3849 	QL_PRINT_3(ha, "started\n");
3850 
3851 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3852 	    QL_SUCCESS) {
3853 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3854 		return (rval);
3855 	}
3856 
3857 	mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3858 	mcp->mb[1] = opt;
3859 	mcp->mb[2] = ha->fcoe_fcf_idx;
3860 	mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3861 	mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3862 	mcp->mb[10] = LSW(size);
3863 	mcp->mb[11] = MSW(size);
3864 	mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3865 	mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3866 	mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3867 	mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3868 	mcp->mb[18] = LSW(it_cnt);
3869 	mcp->mb[19] = MSW(it_cnt);
3870 	mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3871 	mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3872 	mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3873 	    MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3874 	mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3875 	mcp->timeout = it_cnt / 300;
3876 	if (mcp->timeout < MAILBOX_TOV) {
3877 		mcp->timeout = MAILBOX_TOV;
3878 	}
3879 	rval = ql_mailbox_command(ha, mcp);
3880 
3881 	if (rval == QL_SUCCESS) {
3882 		ql_get_mbox_dma_data(&mem_desc, bp);
3883 	}
3884 
3885 	ql_free_dma_resource(ha, &mem_desc);
3886 
3887 	/* Return mailbox data. */
3888 	if (mr != NULL) {
3889 		mr->mb[0] = mcp->mb[0];
3890 		mr->mb[1] = mcp->mb[1];
3891 		mr->mb[2] = mcp->mb[2];
3892 		mr->mb[3] = mcp->mb[3];
3893 		mr->mb[18] = mcp->mb[18];
3894 		mr->mb[19] = mcp->mb[19];
3895 	}
3896 
3897 	if (rval != QL_SUCCESS) {
3898 		EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3899 	} else {
3900 		/*EMPTY*/
3901 		QL_PRINT_3(ha, "done\n");
3902 	}
3903 
3904 	return (rval);
3905 }
3906 
3907 /*
3908  * ql_diag_echo
3909  *	Issue Diag echo mailbox command.  Valid for qla23xx HBA's.
3910  *
3911  * Input:
3912  *	ha:	adapter state pointer.
3913  *	bp:	buffer pointer.
3914  *	size:	buffer size.
3915  *	opt:	command options.
3916  *	mr:	pointer to mailbox status.
3917  *
3918  * Returns:
3919  *	ql local function return status code.
3920  *
3921  * Context:
3922  *	Kernel context.
3923  */
3924 int
ql_diag_echo(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,uint16_t opt,ql_mbx_data_t * mr)3925 ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt,
3926     ql_mbx_data_t *mr)
3927 {
3928 	int		rval;
3929 	dma_mem_t	mem_desc;
3930 	mbx_cmd_t	mc = {0};
3931 	mbx_cmd_t	*mcp = &mc;
3932 
3933 	QL_PRINT_3(ha, "started\n");
3934 
3935 	if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3936 	    QL_SUCCESS) {
3937 		EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3938 		return (rval);
3939 	}
3940 
3941 	mcp->mb[0] = MBC_ECHO;
3942 	mcp->mb[1] = opt;
3943 	mcp->mb[2] = ha->fcoe_fcf_idx;
3944 	mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3945 	mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3946 	mcp->mb[10] = LSW(size);
3947 	mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3948 	mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3949 	mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3950 	mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3951 	mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3952 	mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3953 	mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3954 	    MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3955 	mcp->in_mb = MBX_1|MBX_0;
3956 	mcp->timeout = MAILBOX_TOV;
3957 	rval = ql_mailbox_command(ha, mcp);
3958 
3959 	if (rval == QL_SUCCESS) {
3960 		ql_get_mbox_dma_data(&mem_desc, bp);
3961 	}
3962 
3963 	ql_free_dma_resource(ha, &mem_desc);
3964 
3965 	if (mr != NULL) {
3966 		mr->mb[0] = mcp->mb[0];
3967 	}
3968 
3969 	if (rval != QL_SUCCESS) {
3970 		EL(ha, "failed=%xh, mb1=%xh\n", rval,
3971 		    mcp->mb[1]);
3972 	} else {
3973 		/*EMPTY*/
3974 		QL_PRINT_3(ha, "done\n");
3975 	}
3976 
3977 	return (rval);
3978 }
3979 
3980 /*
3981  * ql_diag_beacon
3982  *      Enable/Disable beaconing via mailbox command.
3983  *
3984  * Input:
3985  *      ha:     adapter state pointer.
3986  *      mr:     pointer to mailbox in/out parameters.
3987  *
3988  * Returns:
3989  *      ql local function return status code.
3990  *
3991  * Context:
3992  *      Kernel context.
3993  */
3994 int
ql_diag_beacon(ql_adapter_state_t * ha,int cmd,ql_mbx_data_t * mr)3995 ql_diag_beacon(ql_adapter_state_t *ha, int cmd, ql_mbx_data_t *mr)
3996 {
3997 	int		rval;
3998 	mbx_cmd_t	mc = {0};
3999 	mbx_cmd_t	*mcp = &mc;
4000 
4001 	mcp->mb[0] = MBC_SET_LED_CONFIG;
4002 	if (cmd == QL_BEACON_ENABLE) {
4003 		mcp->mb[7] = 0xE;
4004 	} else if (cmd == QL_BEACON_DISABLE) {
4005 		mcp->mb[7] = 0xD;
4006 	} else {
4007 		return (EIO);
4008 	}
4009 	mcp->out_mb = MBX_7|MBX_0;
4010 	mcp->in_mb = MBX_0;
4011 	mcp->timeout = MAILBOX_TOV;
4012 
4013 	rval = ql_mailbox_command(ha, mcp);
4014 
4015 	/* Return mailbox data. */
4016 	if (mr != NULL) {
4017 		mr->mb[0] = mcp->mb[0];
4018 	}
4019 
4020 	if (rval != QL_SUCCESS) {
4021 		EL(ha, "failed=%xh\n", rval);
4022 	}
4023 
4024 	return (rval);
4025 }
4026 
4027 
4028 /*
4029  * ql_serdes_param
4030  *	Set/Get serdes transmit parameters mailbox command.
4031  *
4032  * Input:
4033  *	ha:	adapter state pointer.
4034  *	mr:	pointer to mailbox in/out parameters.
4035  *
4036  * Returns:
4037  *	ql local function return status code.
4038  *
4039  * Context:
4040  *	Kernel context.
4041  */
4042 int
ql_serdes_param(ql_adapter_state_t * ha,ql_mbx_data_t * mr)4043 ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4044 {
4045 	int		rval;
4046 	mbx_cmd_t	mc = {0};
4047 	mbx_cmd_t	*mcp = &mc;
4048 
4049 	QL_PRINT_3(ha, "started\n");
4050 
4051 	mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
4052 	mcp->mb[1] = mr->mb[1];
4053 	mcp->mb[2] = mr->mb[2];
4054 	mcp->mb[3] = mr->mb[3];
4055 	mcp->mb[4] = mr->mb[4];
4056 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4057 	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
4058 	mcp->timeout = MAILBOX_TOV;
4059 	rval = ql_mailbox_command(ha, mcp);
4060 
4061 	/* Return mailbox data. */
4062 	mr->mb[0] = mcp->mb[0];
4063 	mr->mb[2] = mcp->mb[2];
4064 	mr->mb[3] = mcp->mb[3];
4065 	mr->mb[4] = mcp->mb[4];
4066 
4067 	if (rval != QL_SUCCESS) {
4068 		EL(ha, "failed=%xh\n", rval);
4069 	} else {
4070 		/*EMPTY*/
4071 		QL_PRINT_3(ha, "done\n");
4072 	}
4073 
4074 	return (rval);
4075 }
4076 
4077 /*
4078  * ql_get_timeout_parameters
4079  *	Issue get timeout parameters mailbox command.
4080  *
4081  * Input:
4082  *	ha:	adapter state pointer.
4083  *	mr:	pointer to mailbox in/out parameters.
4084  *
4085  * Returns:
4086  *	ql local function return status code.
4087  *
4088  * Context:
4089  *	Kernel context.
4090  */
4091 int
ql_get_timeout_parameters(ql_adapter_state_t * ha,uint16_t * tov)4092 ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
4093 {
4094 	int		rval;
4095 	mbx_cmd_t	mc = {0};
4096 	mbx_cmd_t	*mcp = &mc;
4097 
4098 	QL_PRINT_3(ha, "started\n");
4099 
4100 	mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
4101 	mcp->mb[1] = ha->fcoe_fcf_idx;
4102 	mcp->out_mb = MBX_1|MBX_0;
4103 	mcp->in_mb = MBX_3|MBX_0;
4104 	mcp->timeout = MAILBOX_TOV;
4105 	rval = ql_mailbox_command(ha, mcp);
4106 	if (rval == QL_SUCCESS) {
4107 		/* Get 2 * R_A_TOV in seconds */
4108 		if (CFG_IST(ha, CFG_CTRL_22XX) || mcp->mb[3] == 0) {
4109 			*tov = R_A_TOV_DEFAULT;
4110 		} else {
4111 			*tov = (uint16_t)(mcp->mb[3] / 10);
4112 			if (mcp->mb[3] % 10 != 0) {
4113 				*tov = (uint16_t)(*tov + 1);
4114 			}
4115 			/*
4116 			 * Adjust value to prevent driver timeout at the same
4117 			 * time as device.
4118 			 */
4119 			*tov = (uint16_t)(*tov + 5);
4120 		}
4121 	} else {
4122 		*tov = R_A_TOV_DEFAULT;
4123 	}
4124 
4125 	if (rval != QL_SUCCESS) {
4126 		EL(ha, "failed=%xh\n", rval);
4127 	} else {
4128 		/*EMPTY*/
4129 		QL_PRINT_3(ha, "done\n");
4130 	}
4131 
4132 	return (rval);
4133 }
4134 
4135 /*
4136  * ql_stop_firmware
4137  *	 Issue stop firmware Mailbox Command.
4138  *
4139  * Input:
4140  *	ha:	adapter state pointer.
4141  *
4142  * Returns:
4143  *	ql local function return status code.
4144  *
4145  * Context:
4146  *	Kernel context.
4147  */
4148 int
ql_stop_firmware(ql_adapter_state_t * ha)4149 ql_stop_firmware(ql_adapter_state_t *ha)
4150 {
4151 	int		rval;
4152 	mbx_cmd_t	mc = {0};
4153 	mbx_cmd_t	*mcp = &mc;
4154 
4155 	QL_PRINT_3(ha, "started\n");
4156 
4157 	mcp->mb[0] = MBC_STOP_FIRMWARE;
4158 	mcp->out_mb = MBX_1|MBX_0;
4159 	mcp->in_mb = MBX_0;
4160 	mcp->timeout = 2;
4161 	rval = ql_mailbox_command(ha, mcp);
4162 
4163 	if (rval != QL_SUCCESS) {
4164 		EL(ha, "failed=%xh\n", rval);
4165 	} else {
4166 		/*EMPTY*/
4167 		QL_PRINT_3(ha, "done\n");
4168 	}
4169 
4170 	return (rval);
4171 }
4172 
4173 /*
4174  * ql_read_sfp
4175  *	Issue Read SFP Mailbox command
4176  *
4177  * Input:
4178  *	ha:	adapter state pointer.
4179  *	mem:	pointer to dma memory object for command.
4180  *	dev:	Device address (A0h or A2h).
4181  *	addr:	Data address on SFP EEPROM (0-255).
4182  *
4183  * Returns:
4184  *	ql local function return status code.
4185  *
4186  * Context:
4187  *	Kernel context.
4188  */
4189 int
ql_read_sfp(ql_adapter_state_t * ha,dma_mem_t * mem,uint16_t dev,uint16_t addr)4190 ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
4191     uint16_t addr)
4192 {
4193 	int		rval;
4194 	mbx_cmd_t	mc = {0};
4195 	mbx_cmd_t	*mcp = &mc;
4196 
4197 	QL_PRINT_3(ha, "started\n");
4198 
4199 	mcp->mb[0] = MBC_READ_SFP;
4200 	mcp->mb[1] = dev;
4201 	mcp->mb[2] = MSW(mem->cookies->dmac_address);
4202 	mcp->mb[3] = LSW(mem->cookies->dmac_address);
4203 	mcp->mb[6] = MSW(mem->cookies->dmac_notused);
4204 	mcp->mb[7] = LSW(mem->cookies->dmac_notused);
4205 	mcp->mb[8] = LSW(mem->size);
4206 	mcp->mb[9] = addr;
4207 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4208 	mcp->in_mb = MBX_1|MBX_0;
4209 	mcp->timeout = MAILBOX_TOV;
4210 	rval = ql_mailbox_command(ha, mcp);
4211 
4212 	(void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
4213 	    DDI_DMA_SYNC_FORKERNEL);
4214 
4215 	if (rval != QL_SUCCESS) {
4216 		EL(ha, "failed=%xh\n", rval);
4217 	} else {
4218 		/*EMPTY*/
4219 		QL_PRINT_3(ha, "done\n");
4220 	}
4221 
4222 	return (rval);
4223 }
4224 
4225 /*
4226  * ql_iidma_rate
4227  *	Issue get/set iidma rate command
4228  *
4229  * Input:
4230  *	ha:		adapter state pointer.
4231  *	loop_id:	n-port handle to set/get iidma rate.
4232  *	idma_rate:	Pointer to iidma rate.
4233  *	option:		iidma firmware option (set or get data).
4234  *				0 --> Get iidma rate
4235  *				1 --> Set iidma rate
4236  *
4237  * Returns:
4238  *	ql local function return status code.
4239  *
4240  * Context:
4241  *	Kernel context.
4242  */
4243 int
ql_iidma_rate(ql_adapter_state_t * ha,uint16_t loop_id,uint32_t * idma_rate,uint32_t option)4244 ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
4245     uint32_t option)
4246 {
4247 	int		rval;
4248 	mbx_cmd_t	mc = {0};
4249 	mbx_cmd_t	*mcp = &mc;
4250 
4251 	QL_PRINT_3(ha, "started\n");
4252 
4253 	mcp->mb[0] = MBC_PORT_PARAM;
4254 	mcp->mb[1] = loop_id;
4255 	mcp->mb[2] = (uint16_t)option;
4256 	mcp->out_mb = MBX_0|MBX_1|MBX_2;
4257 	mcp->in_mb = MBX_0|MBX_1;
4258 
4259 	if (option & BIT_0) {
4260 		mcp->mb[3] = (uint16_t)*idma_rate;
4261 		mcp->out_mb |= MBX_3;
4262 	} else {
4263 		mcp->in_mb |= MBX_3;
4264 	}
4265 
4266 	mcp->timeout = MAILBOX_TOV;
4267 	rval = ql_mailbox_command(ha, mcp);
4268 
4269 	if (rval != QL_SUCCESS) {
4270 		EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
4271 	} else {
4272 		if (option == 0) {
4273 			*idma_rate = mcp->mb[3];
4274 		}
4275 
4276 		QL_PRINT_3(ha, "done\n");
4277 	}
4278 
4279 	return (rval);
4280 }
4281 
4282 /*
4283  * ql_set_xmit_parms
4284  *	Set transmit parameters
4285  *
4286  * Input:
4287  *	ha:	adapter state pointer.
4288  *
4289  * Returns:
4290  *	ql local function return status code.
4291  *
4292  * Context:
4293  *	Kernel context.
4294  */
4295 int
ql_set_xmit_parms(ql_adapter_state_t * ha)4296 ql_set_xmit_parms(ql_adapter_state_t *ha)
4297 {
4298 	int		rval;
4299 	mbx_cmd_t	mc = {0};
4300 	mbx_cmd_t	*mcp = &mc;
4301 
4302 	QL_PRINT_3(ha, "started\n");
4303 
4304 	mcp->mb[0] = MBC_XMIT_PARM;
4305 	mcp->mb[1] = BIT_1;
4306 	mcp->out_mb = MBX_1|MBX_0;
4307 	mcp->in_mb = MBX_0;
4308 	mcp->timeout = MAILBOX_TOV;
4309 	rval = ql_mailbox_command(ha, mcp);
4310 
4311 	if (rval != QL_SUCCESS) {
4312 		EL(ha, "failed=%xh\n", rval);
4313 	} else {
4314 		/*EMPTY*/
4315 		QL_PRINT_3(ha, "done\n");
4316 	}
4317 	return (rval);
4318 }
4319 
4320 /*
4321  * ql_fw_etrace
4322  *	Firmware extended tracing.
4323  *
4324  * Input:
4325  *	ha:	adapter state pointer.
4326  *	mem:	pointer to dma memory object for command.
4327  *	opt:	options and opcode.
4328  *	mr:	pointer to mailbox in/out parameters.
4329  *
4330  * Returns:
4331  *	ql local function return status code.
4332  *
4333  * Context:
4334  *	Kernel context.
4335  */
4336 int
ql_fw_etrace(ql_adapter_state_t * ha,dma_mem_t * mem,uint16_t opt,ql_mbx_data_t * mr)4337 ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt,
4338     ql_mbx_data_t *mr)
4339 {
4340 	int		rval = QL_SUCCESS;
4341 	mbx_cmd_t	mc = {0};
4342 	mbx_cmd_t	*mcp = &mc;
4343 	uint16_t	op_code;
4344 	uint64_t	time;
4345 
4346 	QL_PRINT_3(ha, "started\n");
4347 
4348 	/* currently no supported options */
4349 	op_code = (uint16_t)(opt & ~0xFF00);
4350 
4351 	mcp->mb[0] = MBC_TRACE_CONTROL;
4352 	mcp->mb[1] = op_code;
4353 	mcp->in_mb = MBX_0;
4354 	mcp->timeout = MAILBOX_TOV;
4355 
4356 	switch (op_code) {
4357 	case FTO_INSERT_TIME_STAMP:
4358 
4359 		(void) drv_getparm(TIME, &time);
4360 
4361 		EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
4362 
4363 		mcp->mb[2] = LSW(LSD(time));
4364 		mcp->mb[3] = MSW(LSD(time));
4365 		mcp->mb[4] = LSW(MSD(time));
4366 		mcp->mb[5] = MSW(MSD(time));
4367 		mcp->out_mb = MBX_0_THRU_5;
4368 		break;
4369 
4370 	case FTO_FCE_TRACE_ENABLE:
4371 		/* Firmware Fibre Channel Event Trace Buffer */
4372 		mcp->mb[2] = LSW(mem->cookies->dmac_address);
4373 		mcp->mb[3] = MSW(mem->cookies->dmac_address);
4374 		mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4375 		mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4376 		mcp->mb[6] = (uint16_t)(mem->size / 0x4000);	/* 16kb blks */
4377 		mcp->mb[8] = (uint16_t)ha->fwfcetraceopt;
4378 		mcp->mb[9] = FTO_FCEMAXTRACEBUF;
4379 		mcp->mb[10] = FTO_FCEMAXTRACEBUF;
4380 		mcp->out_mb = MBX_0_THRU_10;
4381 		break;
4382 
4383 	case FTO_EXT_TRACE_ENABLE:
4384 		/* Firmware Extended Trace Buffer */
4385 		mcp->mb[2] = LSW(mem->cookies->dmac_address);
4386 		mcp->mb[3] = MSW(mem->cookies->dmac_address);
4387 		mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4388 		mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4389 		mcp->mb[6] = (uint16_t)(mem->size / 0x4000);	/* 16kb blks */
4390 		mcp->out_mb = MBX_0_THRU_7;
4391 		break;
4392 
4393 	case FTO_FCE_TRACE_DISABLE:
4394 		/* also causes ISP25xx to flush its internal FCE buffer. */
4395 		mcp->mb[2] = BIT_0;
4396 		mcp->out_mb = MBX_0_THRU_2;
4397 		break;
4398 
4399 	case FTO_EXT_TRACE_DISABLE:
4400 		/* just sending the opcode disables it */
4401 		break;
4402 
4403 	default:
4404 		EL(ha, "invalid option: %xh\n", opt);
4405 		rval = QL_PARAMETER_ERROR;
4406 		break;
4407 	}
4408 
4409 	if (rval == QL_SUCCESS) {
4410 		rval = ql_mailbox_command(ha, mcp);
4411 	}
4412 
4413 	/* Return mailbox data. */
4414 	if (mr != NULL) {
4415 		mr->mb[0] = mcp->mb[0];
4416 		mr->mb[1] = mcp->mb[1];
4417 		mr->mb[2] = mcp->mb[2];
4418 		mr->mb[3] = mcp->mb[3];
4419 		mr->mb[4] = mcp->mb[4];
4420 		mr->mb[5] = mcp->mb[5];
4421 		mr->mb[6] = mcp->mb[6];
4422 		mr->mb[7] = mcp->mb[7];
4423 		mr->mb[8] = mcp->mb[8];
4424 		mr->mb[9] = mcp->mb[9];
4425 	}
4426 
4427 	if (rval != QL_SUCCESS) {
4428 		EL(ha, "failed=%xh\n", rval);
4429 	} else {
4430 		/*EMPTY*/
4431 		QL_PRINT_3(ha, "done\n");
4432 	}
4433 
4434 	return (rval);
4435 }
4436 
4437 /*
4438  * ql_reset_menlo
4439  *	 Reset Menlo Mailbox Command.
4440  *
4441  * Input:
4442  *	ha:	adapter state pointer.
4443  *	mr:	pointer to mailbox in/out parameters.
4444  *	opt:	options.
4445  *
4446  * Returns:
4447  *	ql local function return status code.
4448  *
4449  * Context:
4450  *	Kernel context.
4451  */
4452 int
ql_reset_menlo(ql_adapter_state_t * ha,ql_mbx_data_t * mr,uint16_t opt)4453 ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4454 {
4455 	int		rval;
4456 	mbx_cmd_t	mc = {0};
4457 	mbx_cmd_t	*mcp = &mc;
4458 
4459 	QL_PRINT_3(ha, "started\n");
4460 
4461 	mcp->mb[0] = MBC_RESET_MENLO;
4462 	mcp->mb[1] = opt;
4463 	mcp->out_mb = MBX_1|MBX_0;
4464 	mcp->in_mb = MBX_1|MBX_0;
4465 	mcp->timeout = MAILBOX_TOV;
4466 	rval = ql_mailbox_command(ha, mcp);
4467 
4468 	/* Return mailbox data. */
4469 	if (mr != NULL) {
4470 		mr->mb[0] = mcp->mb[0];
4471 		mr->mb[1] = mcp->mb[1];
4472 	}
4473 
4474 	if (rval != QL_SUCCESS) {
4475 		EL(ha, "failed=%xh\n", rval);
4476 	} else {
4477 		/*EMPTY*/
4478 		QL_PRINT_3(ha, "done\n");
4479 	}
4480 
4481 	return (rval);
4482 }
4483 
4484 /*
4485  * ql_restart_mpi
4486  *	The Restart MPI Firmware Mailbox Command will reset the MPI RISC,
4487  *	reload MPI firmware from Flash, and execute the firmware.
4488  *
4489  * Input:
4490  *	ha:	adapter state pointer.
4491  *
4492  * Returns:
4493  *	ql local function return status code.
4494  *
4495  * Context:
4496  *	Kernel context.
4497  */
4498 int
ql_restart_mpi(ql_adapter_state_t * ha)4499 ql_restart_mpi(ql_adapter_state_t *ha)
4500 {
4501 	int		rval;
4502 	mbx_cmd_t	mc = {0};
4503 	mbx_cmd_t	*mcp = &mc;
4504 
4505 	QL_PRINT_3(ha, "started\n");
4506 
4507 	mcp->mb[0] = MBC_RESTART_MPI;
4508 	mcp->out_mb = MBX_0;
4509 	mcp->in_mb = MBX_1|MBX_0;
4510 	mcp->timeout = MAILBOX_TOV;
4511 	rval = ql_mailbox_command(ha, mcp);
4512 
4513 	/* Return mailbox data. */
4514 	if (rval != QL_SUCCESS) {
4515 		EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
4516 	} else {
4517 		/*EMPTY*/
4518 		QL_PRINT_3(ha, "done\n");
4519 	}
4520 
4521 	return (rval);
4522 }
4523 
4524 /*
4525  * ql_idc_request
4526  *	Inter-Driver Communication Request.
4527  *
4528  * Input:
4529  *	ha:	adapter state pointer.
4530  *	mr:	pointer for mailbox data.
4531  *
4532  * Returns:
4533  *	ql local function return status code.
4534  *
4535  * Context:
4536  *	Kernel context.
4537  */
4538 int
ql_idc_request(ql_adapter_state_t * ha,ql_mbx_data_t * mr)4539 ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4540 {
4541 	int		rval;
4542 	mbx_cmd_t	mc = {0};
4543 	mbx_cmd_t	*mcp = &mc;
4544 
4545 	QL_PRINT_3(ha, "started\n");
4546 
4547 	mcp->mb[0] = MBC_IDC_REQUEST;
4548 	mcp->mb[1] = mr->mb[1];
4549 	mcp->mb[2] = mr->mb[2];
4550 	mcp->mb[3] = mr->mb[3];
4551 	mcp->mb[4] = mr->mb[4];
4552 	mcp->mb[5] = mr->mb[5];
4553 	mcp->mb[6] = mr->mb[6];
4554 	mcp->mb[7] = mr->mb[7];
4555 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4556 	mcp->in_mb = MBX_2|MBX_0;
4557 	mcp->timeout = MAILBOX_TOV;
4558 	rval = ql_mailbox_command(ha, mcp);
4559 
4560 	if (rval == QL_SUCCESS) {
4561 		mr->mb[2] = mcp->mb[2];
4562 		QL_PRINT_3(ha, "done\n");
4563 	} else {
4564 		EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]);
4565 	}
4566 
4567 	return (rval);
4568 }
4569 
4570 /*
4571  * ql_idc_ack
4572  *	Inter-Driver Communication Acknowledgement.
4573  *
4574  * Input:
4575  *	ha:	adapter state pointer.
4576  *
4577  * Returns:
4578  *	ql local function return status code.
4579  *
4580  * Context:
4581  *	Kernel context.
4582  */
4583 int
ql_idc_ack(ql_adapter_state_t * ha)4584 ql_idc_ack(ql_adapter_state_t *ha)
4585 {
4586 	int		rval;
4587 	mbx_cmd_t	mc = {0};
4588 	mbx_cmd_t	*mcp = &mc;
4589 
4590 	QL_PRINT_3(ha, "started\n");
4591 
4592 	mcp->mb[0] = MBC_IDC_ACK;
4593 	mcp->mb[1] = ha->idc_mb[1];
4594 	mcp->mb[2] = ha->idc_mb[2];
4595 	mcp->mb[3] = ha->idc_mb[3];
4596 	mcp->mb[4] = ha->idc_mb[4];
4597 	mcp->mb[5] = ha->idc_mb[5];
4598 	mcp->mb[6] = ha->idc_mb[6];
4599 	mcp->mb[7] = ha->idc_mb[7];
4600 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4601 	mcp->in_mb = MBX_0;
4602 	mcp->timeout = MAILBOX_TOV;
4603 	rval = ql_mailbox_command(ha, mcp);
4604 
4605 	QL_PRINT_3(ha, "done\n");
4606 
4607 	return (rval);
4608 }
4609 
4610 /*
4611  * ql_idc_time_extend
4612  *	Inter-Driver Communication Time Extend
4613  *
4614  * Input:
4615  *	ha:	adapter state pointer.
4616  *
4617  * Returns:
4618  *	ql local function return status code.
4619  *
4620  * Context:
4621  *	Kernel context.
4622  */
4623 int
ql_idc_time_extend(ql_adapter_state_t * ha)4624 ql_idc_time_extend(ql_adapter_state_t *ha)
4625 {
4626 	int		rval;
4627 	mbx_cmd_t	mc = {0};
4628 	mbx_cmd_t	*mcp = &mc;
4629 
4630 	QL_PRINT_3(ha, "started\n");
4631 
4632 	mcp->mb[0] = MBC_IDC_TIME_EXTEND;
4633 	mcp->mb[1] = ha->idc_mb[1];
4634 	mcp->mb[2] = ha->idc_mb[2];
4635 	mcp->mb[3] = ha->idc_mb[3];
4636 	mcp->mb[4] = ha->idc_mb[4];
4637 	mcp->mb[5] = ha->idc_mb[5];
4638 	mcp->mb[6] = ha->idc_mb[6];
4639 	mcp->mb[7] = ha->idc_mb[7];
4640 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4641 	mcp->in_mb = MBX_0;
4642 	mcp->timeout = MAILBOX_TOV;
4643 	rval = ql_mailbox_command(ha, mcp);
4644 
4645 	QL_PRINT_3(ha, "done\n");
4646 
4647 	return (rval);
4648 }
4649 
4650 /*
4651  * ql_port_reset
4652  *	The Port Reset for the external 10G port associated with this function.
4653  *
4654  * Input:
4655  *	ha:	adapter state pointer.
4656  *
4657  * Returns:
4658  *	ql local function return status code.
4659  *
4660  * Context:
4661  *	Kernel context.
4662  */
4663 int
ql_port_reset(ql_adapter_state_t * ha)4664 ql_port_reset(ql_adapter_state_t *ha)
4665 {
4666 	int		rval;
4667 	mbx_cmd_t	mc = {0};
4668 	mbx_cmd_t	*mcp = &mc;
4669 
4670 	QL_PRINT_3(ha, "started\n");
4671 
4672 	mcp->mb[0] = MBC_PORT_RESET;
4673 	mcp->out_mb = MBX_0;
4674 	mcp->in_mb = MBX_0;
4675 	mcp->timeout = MAILBOX_TOV;
4676 	rval = ql_mailbox_command(ha, mcp);
4677 
4678 	QL_PRINT_3(ha, "done\n");
4679 
4680 	return (rval);
4681 }
4682 
4683 /*
4684  * ql_set_port_config
4685  *	The Set Port Configuration command sets the configuration for the
4686  *	external 10G port associated with this function.
4687  *
4688  * Input:
4689  *	ha:	adapter state pointer.
4690  *	mr:	pointer for mailbox data.
4691  *
4692  * Returns:
4693  *	ql local function return status code.
4694  *
4695  * Context:
4696  *	Kernel context.
4697  */
4698 int
ql_set_port_config(ql_adapter_state_t * ha,ql_mbx_data_t * mrp)4699 ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4700 {
4701 	int		rval;
4702 	mbx_cmd_t	mc = {0};
4703 	mbx_cmd_t	*mcp = &mc;
4704 
4705 	QL_PRINT_3(ha, "started\n");
4706 
4707 	mcp->mb[0] = MBC_SET_PORT_CONFIG;
4708 	mcp->mb[1] = mrp->mb[1];
4709 	mcp->mb[2] = mrp->mb[2];
4710 	mcp->mb[3] = mrp->mb[3];
4711 	mcp->mb[4] = mrp->mb[4];
4712 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4713 	mcp->in_mb = MBX_0;
4714 	mcp->timeout = MAILBOX_TOV;
4715 	rval = ql_mailbox_command(ha, mcp);
4716 
4717 	QL_PRINT_3(ha, "done\n");
4718 
4719 	return (rval);
4720 }
4721 
4722 /*
4723  * ql_get_port_config
4724  *	The Get Port Configuration command retrieves the current configuration
4725  *	for the external 10G port associated with this function.
4726  *
4727  * Input:
4728  *	ha:	adapter state pointer.
4729  *	mr:	pointer for mailbox data.
4730  *
4731  * Returns:
4732  *	ql local function return status code.
4733  *
4734  * Context:
4735  *	Kernel context.
4736  */
4737 int
ql_get_port_config(ql_adapter_state_t * ha,ql_mbx_data_t * mrp)4738 ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
4739 {
4740 	int		rval;
4741 	mbx_cmd_t	mc = {0};
4742 	mbx_cmd_t	*mcp = &mc;
4743 
4744 	QL_PRINT_3(ha, "started\n");
4745 
4746 	mcp->mb[0] = MBC_GET_PORT_CONFIG;
4747 	mcp->out_mb = MBX_0;
4748 	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4749 	mcp->timeout = MAILBOX_TOV;
4750 	rval = ql_mailbox_command(ha, mcp);
4751 
4752 	if (rval == QL_SUCCESS) {
4753 		if (mrp != NULL) {
4754 			mrp->mb[1] = mcp->mb[1];
4755 			mrp->mb[2] = mcp->mb[2];
4756 			mrp->mb[3] = mcp->mb[3];
4757 			mrp->mb[4] = mcp->mb[4];
4758 		}
4759 		QL_PRINT_3(ha, "done\n");
4760 	} else {
4761 		EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n",
4762 		    rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]);
4763 	}
4764 
4765 	return (rval);
4766 }
4767 
4768 /*
4769  * ql_flash_access
4770  *	The Get Port Configuration command retrieves the current configuration
4771  *	for the external 10G port associated with this function
4772  *
4773  * Input:
4774  *	ha:	adapter state pointer.
4775  *	cmd:	command.
4776  *	start:	32bit word address.
4777  *	end:	32bit word address.
4778  *	dp:	32bit word pointer.
4779  *
4780  * Returns:
4781  *	ql local function return status code.
4782  *
4783  * Context:
4784  *	Kernel context.
4785  */
4786 int
ql_flash_access(ql_adapter_state_t * ha,uint16_t cmd,uint32_t start,uint32_t end,uint32_t * dp)4787 ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start,
4788     uint32_t end, uint32_t *dp)
4789 {
4790 	int		rval;
4791 	mbx_cmd_t	mc = {0};
4792 	mbx_cmd_t	*mcp = &mc;
4793 
4794 	QL_PRINT_3(ha, "started, cmd=%xh\n", cmd);
4795 
4796 	mcp->mb[0] = MBC_FLASH_ACCESS;
4797 	mcp->mb[1] = cmd;
4798 	mcp->mb[2] = LSW(start);
4799 	mcp->mb[3] = MSW(start);
4800 	mcp->mb[4] = LSW(end);
4801 	mcp->mb[5] = MSW(end);
4802 
4803 	mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4804 	mcp->in_mb = MBX_0_THRU_4;
4805 	mcp->timeout = MAILBOX_TOV;
4806 	rval = ql_mailbox_command(ha, mcp);
4807 
4808 	if (rval != QL_SUCCESS) {
4809 		EL(ha, "cmd=%xh, status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, "
4810 		    "mbx4=%xh\n", cmd, rval, mcp->mb[1], mcp->mb[2],
4811 		    mcp->mb[3], mcp->mb[4]);
4812 	} else {
4813 		if (dp != NULL) {
4814 			*dp = (uint32_t)mcp->mb[1];
4815 		}
4816 		QL_PRINT_3(ha, "done\n");
4817 	}
4818 
4819 	return (rval);
4820 }
4821 
4822 /*
4823  * ql_get_xgmac_stats
4824  *	Issue et XGMAC Statistics Mailbox command
4825  *
4826  * Input:
4827  *	ha:	adapter state pointer.
4828  *	size:	size of data buffer.
4829  *	bufp:	data pointer for DMA data.
4830  *
4831  * Returns:
4832  *	ql local function return status code.
4833  *
4834  * Context:
4835  *	Kernel context.
4836  */
4837 int
ql_get_xgmac_stats(ql_adapter_state_t * ha,size_t size,caddr_t bufp)4838 ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
4839 {
4840 	int		rval;
4841 	dma_mem_t	mem_desc;
4842 	mbx_cmd_t	mc = {0};
4843 	mbx_cmd_t	*mcp = &mc;
4844 
4845 	QL_PRINT_3(ha, "started\n");
4846 
4847 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4848 	    (uint32_t)size)) != QL_SUCCESS) {
4849 		EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
4850 		return (QL_MEMORY_ALLOC_FAILED);
4851 	}
4852 
4853 	mcp->mb[0] = MBC_GET_XGMAC_STATS;
4854 	mcp->mb[2] = MSW(mem_desc.cookie.dmac_address);
4855 	mcp->mb[3] = LSW(mem_desc.cookie.dmac_address);
4856 	mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused);
4857 	mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused);
4858 	mcp->mb[8] = (uint16_t)(size >> 2);
4859 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4860 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
4861 	mcp->timeout = MAILBOX_TOV;
4862 	rval = ql_mailbox_command(ha, mcp);
4863 
4864 	if (rval == QL_SUCCESS) {
4865 		ql_get_mbox_dma_data(&mem_desc, bufp);
4866 	}
4867 	ql_free_dma_resource(ha, &mem_desc);
4868 
4869 	if (rval != QL_SUCCESS) {
4870 		EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4871 		    mcp->mb[2]);
4872 	} else {
4873 		/*EMPTY*/
4874 		QL_PRINT_3(ha, "done\n");
4875 	}
4876 
4877 	return (rval);
4878 }
4879 
4880 /*
4881  * ql_get_dcbx_params
4882  *	Issue get DCBX parameters mailbox command.
4883  *
4884  * Input:
4885  *	ha:	adapter state pointer.
4886  *	size:	size of data buffer.
4887  *	bufp:	data pointer for DMA data.
4888  *
4889  * Returns:
4890  *	ql local function return status code.
4891  *
4892  * Context:
4893  *	Kernel context.
4894  */
4895 int
ql_get_dcbx_params(ql_adapter_state_t * ha,uint32_t size,caddr_t bufp)4896 ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp)
4897 {
4898 	int		rval;
4899 	dma_mem_t	mem_desc;
4900 	mbx_cmd_t	mc = {0};
4901 	mbx_cmd_t	*mcp = &mc;
4902 
4903 	QL_PRINT_3(ha, "started\n");
4904 
4905 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) !=
4906 	    QL_SUCCESS) {
4907 		EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4908 		return (QL_MEMORY_ALLOC_FAILED);
4909 	}
4910 
4911 	mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4912 	mcp->mb[1] = 0;	/* Return all DCBX paramters */
4913 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4914 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4915 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4916 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4917 	mcp->mb[8] = (uint16_t)size;
4918 	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4919 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
4920 	mcp->timeout = MAILBOX_TOV;
4921 	rval = ql_mailbox_command(ha, mcp);
4922 
4923 	if (rval == QL_SUCCESS) {
4924 		ql_get_mbox_dma_data(&mem_desc, bufp);
4925 	}
4926 
4927 	ql_free_dma_resource(ha, &mem_desc);
4928 
4929 	if (rval != QL_SUCCESS) {
4930 		EL(ha, "failed=%xh\n", rval);
4931 	} else {
4932 		/*EMPTY*/
4933 		QL_PRINT_3(ha, "done\n");
4934 	}
4935 
4936 	return (rval);
4937 }
4938 /*
4939  * ql_get_fcf_list
4940  *	Issue get FCF list mailbox command.
4941  *
4942  * Input:
4943  *	ha:		adapter state pointer.
4944  *	fcf_list:	pointer to ql_fcf_list_desc_t
4945  *	bufp:		data pointer for DMA data.
4946  *
4947  * Returns:
4948  *	ql local function return status code.
4949  *
4950  * Context:
4951  *	Kernel context.
4952  */
4953 
4954 int
ql_get_fcf_list_mbx(ql_adapter_state_t * ha,ql_fcf_list_desc_t * fcf_list,caddr_t bufp)4955 ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list,
4956     caddr_t bufp)
4957 {
4958 	int		rval;
4959 	dma_mem_t	mem_desc;
4960 	mbx_cmd_t	mc = {0};
4961 	mbx_cmd_t	*mcp = &mc;
4962 
4963 	QL_PRINT_3(ha, "started\n");
4964 
4965 	if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4966 	    fcf_list->buffer_size)) !=
4967 	    QL_SUCCESS) {
4968 		EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4969 		return (QL_MEMORY_ALLOC_FAILED);
4970 	}
4971 
4972 	mcp->mb[0] = MBC_GET_FCF_LIST;
4973 	mcp->mb[1] = fcf_list->options;
4974 	mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4975 	mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4976 	mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4977 	mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4978 	mcp->mb[8] = (uint16_t)fcf_list->buffer_size;
4979 	mcp->mb[9] = fcf_list->fcf_index;
4980 	mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4981 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
4982 	mcp->timeout = MAILBOX_TOV;
4983 	rval = ql_mailbox_command(ha, mcp);
4984 
4985 	if (rval == QL_SUCCESS) {
4986 		ql_get_mbox_dma_data(&mem_desc, bufp);
4987 		fcf_list->buffer_size = (uint16_t)mcp->mb[1];
4988 	}
4989 
4990 	ql_free_dma_resource(ha, &mem_desc);
4991 
4992 	if (rval != QL_SUCCESS) {
4993 		EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4994 		    mcp->mb[2]);
4995 	} else {
4996 		/*EMPTY*/
4997 		QL_PRINT_3(ha, "done\n");
4998 	}
4999 
5000 	return (rval);
5001 }
5002 
5003 /*
5004  * ql_get_resource_cnts
5005  *	Issue get Resourse Count mailbox command.
5006  *
5007  * Input:
5008  *	ha:	adapter state pointer.
5009  *	mr:	pointer for mailbox data.
5010  *
5011  * Returns:
5012  *	ql local function return status code.
5013  *
5014  * Context:
5015  *	Kernel context.
5016  */
5017 
5018 int
ql_get_resource_cnts(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5019 ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5020 {
5021 	int		rval;
5022 	mbx_cmd_t	mc = {0};
5023 	mbx_cmd_t	*mcp = &mc;
5024 
5025 	QL_PRINT_3(ha, "started\n");
5026 
5027 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
5028 	mcp->out_mb = MBX_9|MBX_1|MBX_0;
5029 	mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
5030 	    MBX_3|MBX_2|MBX_1|MBX_0;
5031 	mcp->timeout = MAILBOX_TOV;
5032 	rval = ql_mailbox_command(ha, mcp);
5033 
5034 	/* Return mailbox data. */
5035 	if (mr != NULL) {
5036 		mr->mb[1] = mcp->mb[1];
5037 		mr->mb[2] = mcp->mb[2];
5038 		mr->mb[3] = mcp->mb[3];
5039 		mr->mb[6] = mcp->mb[6];
5040 		mr->mb[7] = mcp->mb[7];
5041 		mr->mb[10] = mcp->mb[10];
5042 		mr->mb[11] = mcp->mb[11];
5043 		mr->mb[12] = mcp->mb[12];
5044 	}
5045 
5046 	if (rval != QL_SUCCESS) {
5047 		EL(ha, "failed=%xh\n", rval);
5048 	} else {
5049 		/*EMPTY*/
5050 		QL_PRINT_3(ha, "done\n");
5051 	}
5052 
5053 	return (rval);
5054 }
5055 
5056 /*
5057  * ql_toggle_interrupt
5058  *	 Issue Toggle Interrupt Mailbox Command.
5059  *
5060  * Input:
5061  *	ha:	adapter state pointer.
5062  *	opt:	0 = disable, 1 = enable.
5063  *
5064  * Returns:
5065  *	ql local function return status code.
5066  *
5067  * Context:
5068  *	Kernel context.
5069  */
5070 int
ql_toggle_interrupt(ql_adapter_state_t * ha,uint16_t opt)5071 ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt)
5072 {
5073 	int		rval;
5074 	mbx_cmd_t	mc = {0};
5075 	mbx_cmd_t	*mcp = &mc;
5076 
5077 	QL_PRINT_3(ha, "started\n");
5078 
5079 	mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5080 	mcp->mb[1] = opt;
5081 	mcp->out_mb = MBX_1|MBX_0;
5082 	mcp->in_mb = MBX_0;
5083 	mcp->timeout = 2;
5084 	rval = ql_mailbox_command(ha, mcp);
5085 
5086 	if (rval != QL_SUCCESS) {
5087 		EL(ha, "failed=%xh\n", rval);
5088 	} else {
5089 		/*EMPTY*/
5090 		QL_PRINT_3(ha, "done\n");
5091 	}
5092 
5093 	return (rval);
5094 }
5095 
5096 /*
5097  * ql_get_md_template
5098  *	Issue request mini-dump template Mailbox command
5099  *
5100  * Input:
5101  *	ha:	adapter state pointer.
5102  *	mem:	pointer to dma memory object for command.
5103  *	mr:	pointer for return mailboxes.
5104  *	ofst:	template offset.
5105  *	opt:	request command code.
5106  *		GTO_TEMPLATE_SIZE	= Request Template Size.
5107  *		GTO_TEMPLATE		= Request Template.
5108  *
5109  * Returns:
5110  *	ql local function return status code.
5111  *
5112  * Context:
5113  *	Kernel context.
5114  */
5115 int
ql_get_md_template(ql_adapter_state_t * ha,dma_mem_t * mem,ql_mbx_data_t * mr,uint32_t ofst,uint16_t opt)5116 ql_get_md_template(ql_adapter_state_t *ha, dma_mem_t *mem, ql_mbx_data_t *mr,
5117     uint32_t ofst, uint16_t opt)
5118 {
5119 	int		rval;
5120 	mbx_cmd_t	mc = {0};
5121 	mbx_cmd_t	*mcp = &mc;
5122 
5123 	QL_PRINT_3(ha, "started\n");
5124 
5125 	mcp->mb[0] = MBC_GET_MD_TEMPLATE;
5126 	mcp->mb[2] = opt;
5127 	if (mem != NULL) {
5128 		mcp->mb[4] = LSW(mem->cookies->dmac_address);
5129 		mcp->mb[5] = MSW(mem->cookies->dmac_address);
5130 		mcp->mb[6] = LSW(mem->cookies->dmac_notused);
5131 		mcp->mb[7] = MSW(mem->cookies->dmac_notused);
5132 		mcp->mb[8] = LSW(mem->size);
5133 		mcp->mb[9] = MSW(mem->size);
5134 	}
5135 	if (ofst != 0) {
5136 		mcp->mb[10] = LSW(ofst);
5137 		mcp->mb[11] = MSW(ofst);
5138 	}
5139 	mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
5140 	    MBX_2|MBX_1|MBX_0;
5141 	mcp->in_mb = MBX_15|MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5142 	    MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5143 	mcp->timeout = MAILBOX_TOV;
5144 	rval = ql_mailbox_command(ha, mcp);
5145 
5146 	/* Return mailbox data. */
5147 	if (mr != NULL) {
5148 		mr->mb[0] = mcp->mb[0];
5149 		mr->mb[1] = mcp->mb[1];
5150 		mr->mb[2] = mcp->mb[2];
5151 		mr->mb[3] = mcp->mb[3];
5152 		mr->mb[4] = mcp->mb[4];
5153 		mr->mb[5] = mcp->mb[5];
5154 		mr->mb[6] = mcp->mb[6];
5155 		mr->mb[7] = mcp->mb[7];
5156 		mr->mb[8] = mcp->mb[8];
5157 		mr->mb[9] = mcp->mb[9];
5158 		mr->mb[10] = mcp->mb[10];
5159 		mr->mb[11] = mcp->mb[11];
5160 		mr->mb[12] = mcp->mb[12];
5161 		mr->mb[13] = mcp->mb[13];
5162 		mr->mb[12] = mcp->mb[14];
5163 		mr->mb[13] = mcp->mb[15];
5164 	}
5165 
5166 	if (rval != QL_SUCCESS) {
5167 		EL(ha, "failed=%xh\n", rval);
5168 	} else {
5169 		/*EMPTY*/
5170 		QL_PRINT_3(ha, "done\n");
5171 	}
5172 	return (rval);
5173 }
5174 
5175 /*
5176  * ql_init_req_q
5177  *	 Initialize request queue.
5178  *
5179  * Input:
5180  *	ha:	adapter state pointer.
5181  *	req_q:	request queue structure pointer.
5182  *	opt:	Initialize Multiple Queue mailbox command options.
5183  *
5184  * Returns:
5185  *	ql driver local function return status codes
5186  *
5187  * Context:
5188  *	Kernel context.
5189  */
5190 static int
ql_init_req_q(ql_adapter_state_t * ha,ql_request_q_t * req_q,uint16_t opt)5191 ql_init_req_q(ql_adapter_state_t *ha, ql_request_q_t *req_q, uint16_t opt)
5192 {
5193 	int		rval;
5194 	mbx_cmd_t	mc = {0};
5195 	mbx_cmd_t	*mcp = &mc;
5196 
5197 	QL_PRINT_3(ha, "started, req_q_number=%d\n", req_q->req_q_number);
5198 
5199 	if (!(opt & IMO_QOS_UPDATE)) {
5200 		req_q->req_ring_ptr = req_q->req_ring.bp;
5201 		req_q->req_ring_index = 0;
5202 		req_q->req_q_cnt = (uint16_t)(req_q->req_entry_cnt - 1);
5203 		WR32_MBAR_REG(ha, req_q->mbar_req_in, 0);
5204 		if (req_q->req_out_shadow_ptr) {
5205 			*req_q->req_out_shadow_ptr = 0;
5206 		}
5207 	}
5208 
5209 	mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5210 	mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED);
5211 	mcp->mb[2] = MSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5212 	mcp->mb[3] = LSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5213 	mcp->mb[4] = req_q->req_q_number;
5214 	mcp->mb[5] = req_q->req_entry_cnt;
5215 	mcp->mb[6] = MSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5216 	mcp->mb[7] = LSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5217 	mcp->mb[11] = ha->vp_index;
5218 	mcp->mb[12] = 0;
5219 	mcp->mb[14] = 1;
5220 	mcp->out_mb = MBX_0_THRU_14;
5221 	mcp->in_mb = MBX_0_THRU_1;
5222 	mcp->timeout = MAILBOX_TOV;
5223 	rval = ql_mailbox_command(ha, mcp);
5224 
5225 	if (rval != QL_SUCCESS) {
5226 		EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5227 	} else {
5228 		/*EMPTY*/
5229 		QL_PRINT_3(ha, "done\n");
5230 	}
5231 	return (rval);
5232 }
5233 
5234 /*
5235  * ql_init_rsp_q
5236  *	 Initialize response queue.
5237  *
5238  * Input:
5239  *	ha:	adapter state pointer.
5240  *	rsp_q:	response queue structure pointer.
5241  *	opt:	Initialize Multiple Queue mailbox command options.
5242  *
5243  * Returns:
5244  *	ql driver local function return status codes
5245  *
5246  * Context:
5247  *	Kernel context.
5248  */
5249 static int
ql_init_rsp_q(ql_adapter_state_t * ha,ql_response_q_t * rsp_q,uint16_t opt)5250 ql_init_rsp_q(ql_adapter_state_t *ha, ql_response_q_t *rsp_q, uint16_t opt)
5251 {
5252 	int		rval;
5253 	mbx_cmd_t	mc = {0};
5254 	mbx_cmd_t	*mcp = &mc;
5255 
5256 	QL_PRINT_3(ha, "started, rsp_q_number=%d\n", rsp_q->rsp_q_number);
5257 
5258 	if (!(opt & IMO_DELETE_Q)) {
5259 		rsp_q->rsp_ring_ptr = rsp_q->rsp_ring.bp;
5260 		rsp_q->rsp_ring_index = 0;
5261 		WR32_MBAR_REG(ha, rsp_q->mbar_rsp_out, 0);
5262 		if (rsp_q->rsp_in_shadow_ptr) {
5263 			*rsp_q->rsp_in_shadow_ptr = 0;
5264 		}
5265 	}
5266 
5267 	mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5268 	mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED |
5269 	    IMO_RESPONSE_Q_SERVICE);
5270 	mcp->mb[2] = MSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5271 	mcp->mb[3] = LSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5272 	mcp->mb[4] = rsp_q->rsp_q_number;
5273 	mcp->mb[5] = rsp_q->rsp_entry_cnt;
5274 	mcp->mb[6] = MSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5275 	mcp->mb[7] = LSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5276 	mcp->mb[14] = rsp_q->msi_x_vector;
5277 	mcp->out_mb = MBX_0_THRU_14;
5278 	mcp->in_mb = MBX_0_THRU_1;
5279 	mcp->timeout = MAILBOX_TOV;
5280 	rval = ql_mailbox_command(ha, mcp);
5281 
5282 	if (rval != QL_SUCCESS) {
5283 		EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5284 	} else {
5285 		/*EMPTY*/
5286 		QL_PRINT_3(ha, "done\n");
5287 	}
5288 	return (rval);
5289 }
5290 
5291 /*
5292  * ql_load_flash_image
5293  *	Load Flash Firmware.
5294  *
5295  * Input:
5296  *	ha:	adapter state pointer.
5297  *
5298  * Returns:
5299  *	ql local function return status code.
5300  *
5301  * Context:
5302  *	Kernel context.
5303  */
5304 int
ql_load_flash_image(ql_adapter_state_t * ha)5305 ql_load_flash_image(ql_adapter_state_t *ha)
5306 {
5307 	int		rval;
5308 	mbx_cmd_t	mc = {0};
5309 	mbx_cmd_t	*mcp = &mc;
5310 
5311 	QL_PRINT_3(ha, "started\n");
5312 
5313 	mcp->mb[0] = MBC_LOAD_FLASH_IMAGE;
5314 	mcp->out_mb = MBX_0;
5315 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
5316 	mcp->timeout = MAILBOX_TOV;
5317 	rval = ql_mailbox_command(ha, mcp);
5318 
5319 	if (rval != QL_SUCCESS) {
5320 		EL(ha, "failed, rval=%xh, mbx1=%xh, mbx2=%xh\n",
5321 		    rval, mcp->mb[1], mcp->mb[2]);
5322 	} else {
5323 		/*EMPTY*/
5324 		QL_PRINT_3(ha, "done\n");
5325 	}
5326 	return (rval);
5327 }
5328 
5329 /*
5330  * ql_set_led_config
5331  *	Set LED Configuration.
5332  *
5333  * Input:
5334  *	ha:	adapter state pointer.
5335  *	mr:	pointer for mailbox data.
5336  *
5337  * Returns:
5338  *	ql local function return status code.
5339  *
5340  * Context:
5341  *	Kernel context.
5342  */
5343 int
ql_set_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5344 ql_set_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5345 {
5346 	int		rval;
5347 	mbx_cmd_t	mc = {0};
5348 	mbx_cmd_t	*mcp = &mc;
5349 
5350 	QL_PRINT_3(ha, "started\n");
5351 
5352 	mcp->mb[0] = MBC_SET_LED_CONFIG;
5353 	mcp->mb[1] = mr->mb[1];
5354 	mcp->mb[2] = mr->mb[2];
5355 	mcp->mb[3] = mr->mb[3];
5356 	mcp->mb[4] = mr->mb[4];
5357 	mcp->mb[5] = mr->mb[5];
5358 	mcp->mb[6] = mr->mb[6];
5359 	mcp->out_mb = MBX_0_THRU_6;
5360 	mcp->in_mb = MBX_0;
5361 	mcp->timeout = MAILBOX_TOV;
5362 	rval = ql_mailbox_command(ha, mcp);
5363 
5364 	if (rval != QL_SUCCESS) {
5365 		EL(ha, "failed=%xh\n", rval);
5366 	} else {
5367 		/*EMPTY*/
5368 		QL_PRINT_3(ha, "done\n");
5369 	}
5370 
5371 	return (rval);
5372 }
5373 /*
5374  * ql_get_led_config
5375  *	Get LED Configuration.
5376  *
5377  * Input:
5378  *	ha:	adapter state pointer.
5379  *	mr:	pointer for mailbox data.
5380  *
5381  * Returns:
5382  *	ql local function return status code.
5383  *
5384  * Context:
5385  *	Kernel context.
5386  */
5387 int
ql_get_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5388 ql_get_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5389 {
5390 	int		rval;
5391 	mbx_cmd_t	mc = {0};
5392 	mbx_cmd_t	*mcp = &mc;
5393 
5394 	QL_PRINT_3(ha, "started\n");
5395 
5396 	mcp->mb[0] = MBC_GET_LED_CONFIG;
5397 	mcp->out_mb = MBX_0;
5398 	mcp->in_mb = MBX_0_THRU_6;
5399 	mcp->timeout = MAILBOX_TOV;
5400 	rval = ql_mailbox_command(ha, mcp);
5401 
5402 	/* Return config data. */
5403 	if (mr != NULL) {
5404 		mr->mb[1] = mcp->mb[1];
5405 		mr->mb[2] = mcp->mb[2];
5406 		mr->mb[3] = mcp->mb[3];
5407 		mr->mb[4] = mcp->mb[4];
5408 		mr->mb[5] = mcp->mb[5];
5409 		mr->mb[6] = mcp->mb[6];
5410 	}
5411 
5412 	if (rval != QL_SUCCESS) {
5413 		EL(ha, "failed=%xh\n", rval);
5414 	} else {
5415 		/*EMPTY*/
5416 		QL_PRINT_3(ha, "done\n");
5417 	}
5418 
5419 	return (rval);
5420 }
5421 
5422 /*
5423  * ql_led_config
5424  *	Set/Get Fibre Channel LED Configuration command.
5425  *
5426  * Input:
5427  *	ha:	adapter state pointer.
5428  *	opt:	Options.
5429  *	led0:	LED 0 configuration.
5430  *	led1:	LED 1 configuration.
5431  *	led2:	LED 2 configuration.
5432  *	mr:	pointer for mailbox data.
5433  *
5434  * Returns:
5435  *	qlc local function return status code.
5436  *
5437  * Context:
5438  *	Kernel context.
5439  */
5440 int
ql_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5441 ql_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5442 {
5443 	int			rval = QL_SUCCESS;
5444 	mbx_cmd_t		mc = {0};
5445 	mbx_cmd_t		*mcp = &mc;
5446 
5447 	QL_PRINT_3(ha, "started\n");
5448 
5449 	mcp->mb[0] = MBC_FC_LED_CONFIG;
5450 	mcp->mb[1] = mr->mb[1];
5451 	mcp->mb[2] = mr->mb[2];
5452 	mcp->mb[3] = mr->mb[3];
5453 	mcp->mb[4] = mr->mb[4];
5454 	mcp->out_mb = MBX_0_THRU_4;
5455 	mcp->in_mb = MBX_0_THRU_4;
5456 	mcp->timeout = MAILBOX_TOV;
5457 	rval = ql_mailbox_command(ha, mcp);
5458 
5459 	/* Return mailbox data. */
5460 	mr->mb[0] = mcp->mb[0];
5461 	mr->mb[1] = mcp->mb[1];
5462 	mr->mb[2] = mcp->mb[2];
5463 	mr->mb[3] = mcp->mb[3];
5464 	mr->mb[4] = mcp->mb[4];
5465 
5466 	if (rval != QL_SUCCESS) {
5467 		EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5468 	} else {
5469 		/*EMPTY*/
5470 		QL_PRINT_3(ha, "done\n");
5471 	}
5472 	return (rval);
5473 }
5474 
5475 /*
5476  * ql_write_remote_reg
5477  *	Writes a register within another function.
5478  *
5479  * Input:
5480  *	ha:	adapter state pointer.
5481  *	addr:	address.
5482  *	data:	data.
5483  *
5484  * Returns:
5485  *	ql local function return status code.
5486  *
5487  * Context:
5488  *	Kernel context.
5489  */
5490 int
ql_write_remote_reg(ql_adapter_state_t * ha,uint32_t addr,uint32_t data)5491 ql_write_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
5492 {
5493 	int		rval;
5494 	mbx_cmd_t	mc = {0};
5495 	mbx_cmd_t	*mcp = &mc;
5496 
5497 	QL_PRINT_10(ha, "started, addr=%xh, data=%xh\n", addr, data);
5498 
5499 	mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5500 	mcp->mb[1] = LSW(addr);
5501 	mcp->mb[2] = MSW(addr);
5502 	mcp->mb[3] = LSW(data);
5503 	mcp->mb[4] = MSW(data);
5504 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5505 	mcp->in_mb = MBX_1|MBX_0;
5506 	mcp->timeout = MAILBOX_TOV;
5507 	rval = ql_mailbox_command(ha, mcp);
5508 
5509 	if (rval != QL_SUCCESS) {
5510 		EL(ha, "failed=%xh, mbx1=%xh, addr=%xh, data=%xh\n", rval,
5511 		    mcp->mb[1], addr, data);
5512 	} else {
5513 		/*EMPTY*/
5514 		QL_PRINT_10(ha, "done\n");
5515 	}
5516 	return (rval);
5517 }
5518 
5519 /*
5520  * ql_read_remote_reg
5521  *	Read a register within another function.
5522  *
5523  * Input:
5524  *	ha:	adapter state pointer.
5525  *	addr:	address.
5526  *	data:	data pointer.
5527  *
5528  * Returns:
5529  *	qlc local function return status code.
5530  *
5531  * Context:
5532  *	Kernel context.
5533  */
5534 int
ql_read_remote_reg(ql_adapter_state_t * ha,uint32_t addr,uint32_t * dp)5535 ql_read_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t *dp)
5536 {
5537 	int		rval;
5538 	mbx_cmd_t	mc = {0};
5539 	mbx_cmd_t	*mcp = &mc;
5540 
5541 	QL_PRINT_10(ha, "started, addr=%xh\n", addr);
5542 
5543 	mcp->mb[0] = MBC_READ_REMOTE_REG;
5544 	mcp->mb[1] = LSW(addr);
5545 	mcp->mb[2] = MSW(addr);
5546 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
5547 	mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5548 	mcp->timeout = MAILBOX_TOV;
5549 	rval = ql_mailbox_command(ha, mcp);
5550 
5551 	if (rval != QL_SUCCESS) {
5552 		EL(ha, "failed=%xh, mbx1=%xh, addr=%xh\n", rval, mcp->mb[1],
5553 		    addr);
5554 	} else {
5555 		*dp = SHORT_TO_LONG(mcp->mb[3], mcp->mb[4]);
5556 		QL_PRINT_10(ha, "done, addr=%xh, data=%xh\n", addr, *dp);
5557 	}
5558 	return (rval);
5559 }
5560 
5561 /*
5562  * ql_get_temp
5563  *	Issue get temperature mailbox command.
5564  *
5565  * Input:
5566  *	ha:	adapter state pointer.
5567  *	mr:	pointer for mailbox data.
5568  *
5569  * Returns:
5570  *	ql local function return status code.
5571  *
5572  * Context:
5573  *	Kernel context.
5574  */
5575 int
ql_get_temp(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5576 ql_get_temp(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5577 {
5578 	int		rval;
5579 	mbx_cmd_t	mc = {0};
5580 	mbx_cmd_t	*mcp = &mc;
5581 
5582 	QL_PRINT_3(ha, "started\n");
5583 
5584 	mcp->mb[0] = MBC_GET_PARAMETERS;
5585 	mcp->mb[1] = READ_ASIC_TEMP << 8;
5586 	mcp->out_mb = MBX_0_THRU_1;
5587 	mcp->in_mb = MBX_0_THRU_1;
5588 	mcp->timeout = MAILBOX_TOV;
5589 	rval = ql_mailbox_command(ha, mcp);
5590 
5591 	/* Return config data. */
5592 	if (mr != NULL) {
5593 		mr->mb[1] = mcp->mb[1];
5594 	}
5595 
5596 	if (rval != QL_SUCCESS) {
5597 		EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5598 	} else {
5599 		/*EMPTY*/
5600 		QL_PRINT_3(ha, "done\n");
5601 	}
5602 	return (rval);
5603 }
5604 
5605 /*
5606  * ql_write_serdes
5607  *	Issue write FC serdes register mailbox command.
5608  *
5609  * Input:
5610  *	ha:	adapter state pointer.
5611  *	mr:	pointer for mailbox data.
5612  *
5613  * Returns:
5614  *	ql local function return status code.
5615  *
5616  * Context:
5617  *	Kernel context.
5618  */
5619 int
ql_write_serdes(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5620 ql_write_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5621 {
5622 	int		rval;
5623 	mbx_cmd_t	mc = {0};
5624 	mbx_cmd_t	*mcp = &mc;
5625 
5626 	QL_PRINT_3(ha, "started\n");
5627 
5628 	mcp->mb[0] = MBC_WRITE_SERDES_REG;
5629 	mcp->mb[1] = mr->mb[1];
5630 	mcp->mb[2] = mr->mb[2];
5631 	mcp->mb[3] = mr->mb[3];
5632 	mcp->mb[4] = mr->mb[4];
5633 	mcp->mb[5] = mr->mb[5];
5634 	mcp->mb[6] = mr->mb[6];
5635 	mcp->out_mb = MBX_0_THRU_6;
5636 	mcp->in_mb = MBX_0;
5637 	mcp->timeout = MAILBOX_TOV;
5638 	rval = ql_mailbox_command(ha, mcp);
5639 
5640 	if (rval != QL_SUCCESS) {
5641 		EL(ha, "failed, rval=%xh\n", rval);
5642 	} else {
5643 		/*EMPTY*/
5644 		QL_PRINT_3(ha, "done\n");
5645 	}
5646 
5647 	return (rval);
5648 }
5649 
5650 /*
5651  * ql_read_serdes
5652  *	Issue read FC serdes register mailbox command.
5653  *
5654  * Input:
5655  *	ha:	adapter state pointer.
5656  *	mr:	pointer for mailbox data.
5657  *
5658  * Returns:
5659  *	ql local function return status code.
5660  *
5661  * Context:
5662  *	Kernel context.
5663  */
5664 int
ql_read_serdes(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5665 ql_read_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5666 {
5667 	int		rval;
5668 	mbx_cmd_t	mc = {0};
5669 	mbx_cmd_t	*mcp = &mc;
5670 
5671 	QL_PRINT_3(ha, "started\n");
5672 
5673 	mcp->mb[0] = MBC_READ_SERDES_REG;
5674 	mcp->mb[1] = mr->mb[1];
5675 	mcp->mb[2] = mr->mb[2];
5676 	mcp->mb[3] = mr->mb[3];
5677 	mcp->mb[4] = mr->mb[4];
5678 	mcp->mb[5] = mr->mb[5];
5679 	mcp->mb[6] = mr->mb[6];
5680 	mcp->out_mb = MBX_0_THRU_6;
5681 	mcp->in_mb = MBX_0_THRU_6;
5682 	mcp->timeout = MAILBOX_TOV;
5683 	rval = ql_mailbox_command(ha, mcp);
5684 
5685 	/* Return mailbox data. */
5686 	mr->mb[0] = mcp->mb[0];
5687 	mr->mb[1] = mcp->mb[1];
5688 	mr->mb[2] = mcp->mb[2];
5689 	mr->mb[3] = mcp->mb[3];
5690 	mr->mb[4] = mcp->mb[4];
5691 	mr->mb[4] = mcp->mb[5];
5692 	mr->mb[4] = mcp->mb[6];
5693 
5694 	if (rval != QL_SUCCESS) {
5695 		EL(ha, "failed, rval=%xh", rval);
5696 	} else {
5697 		/*EMPTY*/
5698 		QL_PRINT_3(ha, "done\n");
5699 	}
5700 
5701 	return (rval);
5702 }
5703