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