1bafec742SSukumar Swaminathan /*
2bafec742SSukumar Swaminathan  * CDDL HEADER START
3bafec742SSukumar Swaminathan  *
4bafec742SSukumar Swaminathan  * The contents of this file are subject to the terms of the
5bafec742SSukumar Swaminathan  * Common Development and Distribution License (the "License").
6bafec742SSukumar Swaminathan  * You may not use this file except in compliance with the License.
7bafec742SSukumar Swaminathan  *
8bafec742SSukumar Swaminathan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9bafec742SSukumar Swaminathan  * or http://www.opensolaris.org/os/licensing.
10bafec742SSukumar Swaminathan  * See the License for the specific language governing permissions
11bafec742SSukumar Swaminathan  * and limitations under the License.
12bafec742SSukumar Swaminathan  *
13bafec742SSukumar Swaminathan  * When distributing Covered Code, include this CDDL HEADER in each
14bafec742SSukumar Swaminathan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15bafec742SSukumar Swaminathan  * If applicable, add the following below this CDDL HEADER, with the
16bafec742SSukumar Swaminathan  * fields enclosed by brackets "[]" replaced with your own identifying
17bafec742SSukumar Swaminathan  * information: Portions Copyright [yyyy] [name of copyright owner]
18bafec742SSukumar Swaminathan  *
19bafec742SSukumar Swaminathan  * CDDL HEADER END
20bafec742SSukumar Swaminathan  */
21bafec742SSukumar Swaminathan 
22bafec742SSukumar Swaminathan /*
23accf27a5SSukumar Swaminathan  * Copyright 2010 QLogic Corporation. All rights reserved.
24bafec742SSukumar Swaminathan  */
25bafec742SSukumar Swaminathan 
26bafec742SSukumar Swaminathan #include <qlge.h>
27bafec742SSukumar Swaminathan 
28bafec742SSukumar Swaminathan static int ql_async_event_parser(qlge_t *, mbx_data_t *);
29bafec742SSukumar Swaminathan 
30bafec742SSukumar Swaminathan /*
31bafec742SSukumar Swaminathan  * Wait upto timeout seconds for Processor Interrupt
32bafec742SSukumar Swaminathan  * if timeout is 0, then wait for default waittime
33bafec742SSukumar Swaminathan  */
34bafec742SSukumar Swaminathan static int
ql_poll_processor_intr(qlge_t * qlge,uint8_t timeout)35bafec742SSukumar Swaminathan ql_poll_processor_intr(qlge_t *qlge, uint8_t timeout)
36bafec742SSukumar Swaminathan {
37bafec742SSukumar Swaminathan 	int rtn_val = DDI_SUCCESS;
38bafec742SSukumar Swaminathan 
39bafec742SSukumar Swaminathan 	if (ql_wait_reg_bit(qlge, REG_STATUS, STS_PI, BIT_SET, timeout)
40bafec742SSukumar Swaminathan 	    != DDI_SUCCESS) {
41bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "Polling for processor interrupt failed.");
42bafec742SSukumar Swaminathan 		rtn_val = DDI_FAILURE;
43bafec742SSukumar Swaminathan 	}
44bafec742SSukumar Swaminathan 	return (rtn_val);
45bafec742SSukumar Swaminathan }
46bafec742SSukumar Swaminathan 
47bafec742SSukumar Swaminathan /*
48bafec742SSukumar Swaminathan  * Wait for mailbox Processor Register Ready
49bafec742SSukumar Swaminathan  */
50bafec742SSukumar Swaminathan static int
ql_wait_processor_addr_reg_ready(qlge_t * qlge)51bafec742SSukumar Swaminathan ql_wait_processor_addr_reg_ready(qlge_t *qlge)
52bafec742SSukumar Swaminathan {
53bafec742SSukumar Swaminathan 	int rtn_val = DDI_SUCCESS;
54bafec742SSukumar Swaminathan 
55bafec742SSukumar Swaminathan 	if (ql_wait_reg_bit(qlge, REG_PROCESSOR_ADDR,
56bafec742SSukumar Swaminathan 	    PROCESSOR_ADDRESS_RDY, BIT_SET, 0) != DDI_SUCCESS) {
57bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
58bafec742SSukumar Swaminathan 		    "Wait for processor address register ready timeout.");
59bafec742SSukumar Swaminathan 		rtn_val = DDI_FAILURE;
60bafec742SSukumar Swaminathan 	}
61bafec742SSukumar Swaminathan 	return (rtn_val);
62bafec742SSukumar Swaminathan }
63bafec742SSukumar Swaminathan 
64bafec742SSukumar Swaminathan /*
65bafec742SSukumar Swaminathan  * Read and write MPI registers using the indirect register interface
66bafec742SSukumar Swaminathan  * Assume all the locks&semaphore have been acquired
67bafec742SSukumar Swaminathan  */
68bafec742SSukumar Swaminathan int
ql_write_processor_data(qlge_t * qlge,uint32_t addr,uint32_t data)69bafec742SSukumar Swaminathan ql_write_processor_data(qlge_t *qlge, uint32_t addr, uint32_t data)
70bafec742SSukumar Swaminathan {
71bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
72bafec742SSukumar Swaminathan 
73bafec742SSukumar Swaminathan 	/* wait for processor address register ready */
74bafec742SSukumar Swaminathan 	if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
75bafec742SSukumar Swaminathan 		goto out;
76bafec742SSukumar Swaminathan 	/* write the data to the data reg */
77bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_PROCESSOR_DATA, data);
78bafec742SSukumar Swaminathan 	/* trigger the write */
79bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
80bafec742SSukumar Swaminathan 	/* wait for register to come ready */
81bafec742SSukumar Swaminathan 	if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
82bafec742SSukumar Swaminathan 		goto out;
83bafec742SSukumar Swaminathan 
84bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
85bafec742SSukumar Swaminathan 
86bafec742SSukumar Swaminathan out:
87bafec742SSukumar Swaminathan 	return (rtn_val);
88bafec742SSukumar Swaminathan 
89bafec742SSukumar Swaminathan }
90bafec742SSukumar Swaminathan 
91bafec742SSukumar Swaminathan /*
92bafec742SSukumar Swaminathan  * Read from processor register
93bafec742SSukumar Swaminathan  */
94bafec742SSukumar Swaminathan int
ql_read_processor_data(qlge_t * qlge,uint32_t addr,uint32_t * data)95bafec742SSukumar Swaminathan ql_read_processor_data(qlge_t *qlge, uint32_t addr, uint32_t *data)
96bafec742SSukumar Swaminathan {
97bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
98bafec742SSukumar Swaminathan 
99bafec742SSukumar Swaminathan 	/* enable read operation */
100bafec742SSukumar Swaminathan 	addr |= PROCESSOR_ADDRESS_READ;
101bafec742SSukumar Swaminathan 	/* wait for processor address register ready */
102bafec742SSukumar Swaminathan 	if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
103bafec742SSukumar Swaminathan 		goto out;
104bafec742SSukumar Swaminathan 
105bafec742SSukumar Swaminathan 	/* Write read address, wait for data ready in Data register */
106bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
107bafec742SSukumar Swaminathan 	/* wait for data ready */
108bafec742SSukumar Swaminathan 	if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
109bafec742SSukumar Swaminathan 		goto out;
110bafec742SSukumar Swaminathan 	/* read data */
111bafec742SSukumar Swaminathan 	*data = ql_read_reg(qlge, REG_PROCESSOR_DATA);
112bafec742SSukumar Swaminathan 
113bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
114bafec742SSukumar Swaminathan 
115bafec742SSukumar Swaminathan out:
116bafec742SSukumar Swaminathan 	return (rtn_val);
117bafec742SSukumar Swaminathan 
118bafec742SSukumar Swaminathan }
119bafec742SSukumar Swaminathan 
120bafec742SSukumar Swaminathan /*
121bafec742SSukumar Swaminathan  * Read "count" number of outgoing Mailbox register starting
122bafec742SSukumar Swaminathan  * from mailbox #0 if count is 0 then read all mailboxes
123bafec742SSukumar Swaminathan  */
124bafec742SSukumar Swaminathan static int
ql_read_mailbox_cmd(qlge_t * qlge,mbx_data_t * mbx_buf,uint32_t count)125bafec742SSukumar Swaminathan ql_read_mailbox_cmd(qlge_t *qlge, mbx_data_t *mbx_buf, uint32_t count)
126bafec742SSukumar Swaminathan {
127bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
128bafec742SSukumar Swaminathan 	uint32_t reg_status;
129bafec742SSukumar Swaminathan 	uint32_t addr;
130bafec742SSukumar Swaminathan 	int i;
131bafec742SSukumar Swaminathan 
132bafec742SSukumar Swaminathan 	if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
133bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
134bafec742SSukumar Swaminathan 		    "%s(%d) get QL_PROCESSOR_SEM_MASK time out error",
135bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
136bafec742SSukumar Swaminathan 		return (DDI_FAILURE);
137bafec742SSukumar Swaminathan 	}
138bafec742SSukumar Swaminathan 
139bafec742SSukumar Swaminathan 	if (qlge->func_number == qlge->fn0_net)
140bafec742SSukumar Swaminathan 		addr = FUNC_0_OUT_MAILBOX_0_REG_OFFSET;
141bafec742SSukumar Swaminathan 	else
142bafec742SSukumar Swaminathan 		addr = FUNC_1_OUT_MAILBOX_0_REG_OFFSET;
143bafec742SSukumar Swaminathan 
144bafec742SSukumar Swaminathan 	if (count == 0)
145bafec742SSukumar Swaminathan 		count = NUM_MAILBOX_REGS;
146bafec742SSukumar Swaminathan 	for (i = 0; i < count; i++) {
147bafec742SSukumar Swaminathan 		if (ql_read_processor_data(qlge, addr, &reg_status)
148bafec742SSukumar Swaminathan 		    == DDI_FAILURE)
149bafec742SSukumar Swaminathan 			goto out;
150bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) mailbox %d value 0x%x\n",
151bafec742SSukumar Swaminathan 		    __func__, qlge->instance, i, reg_status));
152bafec742SSukumar Swaminathan 		mbx_buf->mb[i] = reg_status;
153bafec742SSukumar Swaminathan 		addr ++;
154bafec742SSukumar Swaminathan 	}
155bafec742SSukumar Swaminathan 
156bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
157bafec742SSukumar Swaminathan 
158bafec742SSukumar Swaminathan out:
159bafec742SSukumar Swaminathan 	ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
160bafec742SSukumar Swaminathan 
161bafec742SSukumar Swaminathan 	return (rtn_val);
162bafec742SSukumar Swaminathan 
163bafec742SSukumar Swaminathan }
164bafec742SSukumar Swaminathan 
165bafec742SSukumar Swaminathan /*
166bafec742SSukumar Swaminathan  * Write mail box command (upto 16) to MPI Firmware
167bafec742SSukumar Swaminathan  */
168bafec742SSukumar Swaminathan int
ql_issue_mailbox_cmd(qlge_t * qlge,mbx_cmd_t * mbx_cmd)169bafec742SSukumar Swaminathan ql_issue_mailbox_cmd(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
170bafec742SSukumar Swaminathan {
171bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
172bafec742SSukumar Swaminathan 	uint32_t addr;
173bafec742SSukumar Swaminathan 	int i;
174bafec742SSukumar Swaminathan 	/*
175bafec742SSukumar Swaminathan 	 * Get semaphore to access Processor Address and
176bafec742SSukumar Swaminathan 	 * Processor Data Registers
177bafec742SSukumar Swaminathan 	 */
178bafec742SSukumar Swaminathan 	if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
179bafec742SSukumar Swaminathan 		return (DDI_FAILURE);
180bafec742SSukumar Swaminathan 	}
181bafec742SSukumar Swaminathan 	/* ensure no overwriting current command */
182bafec742SSukumar Swaminathan 	if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS,
183bafec742SSukumar Swaminathan 	    HOST_TO_MPI_INTR_NOT_DONE, BIT_RESET, 0) != DDI_SUCCESS) {
184bafec742SSukumar Swaminathan 		goto out;
185bafec742SSukumar Swaminathan 	}
186bafec742SSukumar Swaminathan 
187bafec742SSukumar Swaminathan 	if (qlge->func_number == qlge->fn0_net)
188bafec742SSukumar Swaminathan 		addr = FUNC_0_IN_MAILBOX_0_REG_OFFSET;
189bafec742SSukumar Swaminathan 	else
190bafec742SSukumar Swaminathan 		addr = FUNC_1_IN_MAILBOX_0_REG_OFFSET;
191bafec742SSukumar Swaminathan 
192bafec742SSukumar Swaminathan 	/* wait for mailbox registers to be ready to access */
193bafec742SSukumar Swaminathan 	if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
194bafec742SSukumar Swaminathan 		goto out;
195bafec742SSukumar Swaminathan 
196bafec742SSukumar Swaminathan 	/* issue mailbox command one by one */
197bafec742SSukumar Swaminathan 	for (i = 0; i < NUM_MAILBOX_REGS; i++) {
198bafec742SSukumar Swaminathan 		/* write sending cmd to mailbox data register */
199bafec742SSukumar Swaminathan 		ql_write_reg(qlge, REG_PROCESSOR_DATA, mbx_cmd->mb[i]);
200bafec742SSukumar Swaminathan 		/* write mailbox address to address register */
201bafec742SSukumar Swaminathan 		ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
202bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) write %x to mailbox(%x) addr %x \n",
203bafec742SSukumar Swaminathan 		    __func__, qlge->instance, mbx_cmd->mb[i], i, addr));
204bafec742SSukumar Swaminathan 		addr++;
205bafec742SSukumar Swaminathan 		/*
206bafec742SSukumar Swaminathan 		 * wait for mailbox cmd to be written before
207bafec742SSukumar Swaminathan 		 * next write can start
208bafec742SSukumar Swaminathan 		 */
209bafec742SSukumar Swaminathan 		if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
210bafec742SSukumar Swaminathan 			goto out;
211bafec742SSukumar Swaminathan 	}
212bafec742SSukumar Swaminathan 	/* inform MPI that new mailbox commands are available */
213bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_INTR);
214bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
215bafec742SSukumar Swaminathan out:
216bafec742SSukumar Swaminathan 	ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
217bafec742SSukumar Swaminathan 	return (rtn_val);
218bafec742SSukumar Swaminathan }
219bafec742SSukumar Swaminathan 
220bafec742SSukumar Swaminathan /*
221bafec742SSukumar Swaminathan  * Send mail box command (upto 16) to MPI Firmware
222bafec742SSukumar Swaminathan  * and polling for MPI mailbox completion response when
223bafec742SSukumar Swaminathan  * interrupt is not enabled.
224bafec742SSukumar Swaminathan  * The MBX_LOCK mutexe should have been held and released
225bafec742SSukumar Swaminathan  * externally
226bafec742SSukumar Swaminathan  */
227bafec742SSukumar Swaminathan int
ql_issue_mailbox_cmd_and_poll_rsp(qlge_t * qlge,mbx_cmd_t * mbx_cmd,mbx_data_t * p_results)228bafec742SSukumar Swaminathan ql_issue_mailbox_cmd_and_poll_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd,
229bafec742SSukumar Swaminathan     mbx_data_t *p_results)
230bafec742SSukumar Swaminathan {
231bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
232bafec742SSukumar Swaminathan 	boolean_t done;
233bafec742SSukumar Swaminathan 	int max_wait;
234bafec742SSukumar Swaminathan 
235bafec742SSukumar Swaminathan 	if (mbx_cmd == NULL)
236bafec742SSukumar Swaminathan 		goto err;
237bafec742SSukumar Swaminathan 
238bafec742SSukumar Swaminathan 	rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
239bafec742SSukumar Swaminathan 	if (rtn_val != DDI_SUCCESS) {
240bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
241bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
242bafec742SSukumar Swaminathan 		goto err;
243bafec742SSukumar Swaminathan 	}
244bafec742SSukumar Swaminathan 	done = B_FALSE;
245bafec742SSukumar Swaminathan 	max_wait = 5; /* wait upto 5 PI interrupt */
246bafec742SSukumar Swaminathan 	/* delay for the processor interrupt is received */
247bafec742SSukumar Swaminathan 	while ((done != B_TRUE) && (max_wait--)) {
248bafec742SSukumar Swaminathan 		/* wait up to 5s for PI interrupt */
249bafec742SSukumar Swaminathan 		if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmd->timeout)
250bafec742SSukumar Swaminathan 		    == DDI_SUCCESS) {
251bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
252bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
2530662fbf4SSukumar Swaminathan 			(void) ql_read_mailbox_cmd(qlge, p_results, 0);
254bafec742SSukumar Swaminathan 			/*
255bafec742SSukumar Swaminathan 			 * Sometimes, the incoming messages is not what we are
256bafec742SSukumar Swaminathan 			 * waiting for, ie. async events, then, continue to
257bafec742SSukumar Swaminathan 			 * wait. If it is the result * of previous mailbox
258bafec742SSukumar Swaminathan 			 * command, then Done. No matter what, send
259bafec742SSukumar Swaminathan 			 * HOST_CMD_CLEAR_RISC_TO_HOST_INTR to clear each
260bafec742SSukumar Swaminathan 			 * PI interrupt
261bafec742SSukumar Swaminathan 			 */
262bafec742SSukumar Swaminathan 			if (ql_async_event_parser(qlge, p_results) == B_FALSE) {
263bafec742SSukumar Swaminathan 				/*
264bafec742SSukumar Swaminathan 				 * we get what we are waiting for,
265bafec742SSukumar Swaminathan 				 * clear the interrupt
266bafec742SSukumar Swaminathan 				 */
267bafec742SSukumar Swaminathan 				rtn_val = DDI_SUCCESS;
268bafec742SSukumar Swaminathan 				done = B_TRUE;
269bafec742SSukumar Swaminathan 			} else {
270bafec742SSukumar Swaminathan 				/*EMPTY*/
271bafec742SSukumar Swaminathan 				QL_PRINT(DBG_MBX,
272bafec742SSukumar Swaminathan 				    ("%s(%d) result ignored, not we wait for\n",
273bafec742SSukumar Swaminathan 				    __func__, qlge->instance));
274bafec742SSukumar Swaminathan 			}
275bafec742SSukumar Swaminathan 			ql_write_reg(qlge, REG_HOST_CMD_STATUS,
276bafec742SSukumar Swaminathan 			    HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
277bafec742SSukumar Swaminathan 		} else { /* timeout */
278bafec742SSukumar Swaminathan 			done = B_TRUE;
279bafec742SSukumar Swaminathan 		}
280bafec742SSukumar Swaminathan 		rtn_val = DDI_SUCCESS;
281bafec742SSukumar Swaminathan 	}
282bafec742SSukumar Swaminathan err:
283bafec742SSukumar Swaminathan 	return (rtn_val);
284bafec742SSukumar Swaminathan }
285bafec742SSukumar Swaminathan /*
286bafec742SSukumar Swaminathan  * Send mail box command (upto 16) to MPI Firmware
287bafec742SSukumar Swaminathan  * and wait for MPI mailbox completion response which
288bafec742SSukumar Swaminathan  * is saved in interrupt. Thus, this function can only
289bafec742SSukumar Swaminathan  * be used after interrupt is enabled.
290bafec742SSukumar Swaminathan  * Must hold MBX mutex before calling this function
291bafec742SSukumar Swaminathan  */
292bafec742SSukumar Swaminathan static int
ql_issue_mailbox_cmd_and_wait_rsp(qlge_t * qlge,mbx_cmd_t * mbx_cmd)293bafec742SSukumar Swaminathan ql_issue_mailbox_cmd_and_wait_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
294bafec742SSukumar Swaminathan {
295bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
296bafec742SSukumar Swaminathan 	clock_t timer;
297bafec742SSukumar Swaminathan 	int i;
298bafec742SSukumar Swaminathan 	int done = 0;
299bafec742SSukumar Swaminathan 
300bafec742SSukumar Swaminathan 	if (mbx_cmd == NULL)
301bafec742SSukumar Swaminathan 		goto err;
302bafec742SSukumar Swaminathan 
303bafec742SSukumar Swaminathan 	ASSERT(mutex_owned(&qlge->mbx_mutex));
304bafec742SSukumar Swaminathan 
305bafec742SSukumar Swaminathan 	/* if interrupts are not enabled, poll when results are available */
306bafec742SSukumar Swaminathan 	if (!(qlge->flags & INTERRUPTS_ENABLED)) {
307bafec742SSukumar Swaminathan 		rtn_val = ql_issue_mailbox_cmd_and_poll_rsp(qlge, mbx_cmd,
308bafec742SSukumar Swaminathan 		    &qlge->received_mbx_cmds);
309bafec742SSukumar Swaminathan 		if (rtn_val == DDI_SUCCESS) {
310bafec742SSukumar Swaminathan 			for (i = 0; i < NUM_MAILBOX_REGS; i++)
311bafec742SSukumar Swaminathan 				mbx_cmd->mb[i] = qlge->received_mbx_cmds.mb[i];
312bafec742SSukumar Swaminathan 		}
313bafec742SSukumar Swaminathan 	} else {
314bafec742SSukumar Swaminathan 		rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
315bafec742SSukumar Swaminathan 		if (rtn_val != DDI_SUCCESS) {
316bafec742SSukumar Swaminathan 			cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
317bafec742SSukumar Swaminathan 			    __func__, qlge->instance);
318bafec742SSukumar Swaminathan 			goto err;
319bafec742SSukumar Swaminathan 		}
320bafec742SSukumar Swaminathan 		qlge->mbx_wait_completion = 1;
321bafec742SSukumar Swaminathan 		while (!done && qlge->mbx_wait_completion && !ddi_in_panic()) {
322bafec742SSukumar Swaminathan 			/* default 5 seconds from now to timeout */
323bafec742SSukumar Swaminathan 			timer = ddi_get_lbolt();
324bafec742SSukumar Swaminathan 			if (mbx_cmd->timeout) {
325bafec742SSukumar Swaminathan 				timer +=
326bafec742SSukumar Swaminathan 				    mbx_cmd->timeout * drv_usectohz(1000000);
327bafec742SSukumar Swaminathan 			} else {
328bafec742SSukumar Swaminathan 				timer += 5 * drv_usectohz(1000000);
329bafec742SSukumar Swaminathan 			}
330bafec742SSukumar Swaminathan 			if (cv_timedwait(&qlge->cv_mbx_intr, &qlge->mbx_mutex,
331bafec742SSukumar Swaminathan 			    timer) == -1) {
332bafec742SSukumar Swaminathan 				/*
333bafec742SSukumar Swaminathan 				 * The timeout time 'timer' was
334bafec742SSukumar Swaminathan 				 * reached or expired without the condition
335bafec742SSukumar Swaminathan 				 * being signaled.
336bafec742SSukumar Swaminathan 				 */
337bafec742SSukumar Swaminathan 				cmn_err(CE_WARN, "%s(%d) Wait for Mailbox cmd "
338bafec742SSukumar Swaminathan 				    "complete timeout.",
339bafec742SSukumar Swaminathan 				    __func__, qlge->instance);
340bafec742SSukumar Swaminathan 				rtn_val = DDI_FAILURE;
341bafec742SSukumar Swaminathan 				done = 1;
342bafec742SSukumar Swaminathan 			} else {
343bafec742SSukumar Swaminathan 				QL_PRINT(DBG_MBX,
344bafec742SSukumar Swaminathan 				    ("%s(%d) mailbox completion signal received"
345bafec742SSukumar Swaminathan 				    " \n", __func__, qlge->instance));
346bafec742SSukumar Swaminathan 				for (i = 0; i < NUM_MAILBOX_REGS; i++) {
347bafec742SSukumar Swaminathan 					mbx_cmd->mb[i] =
348bafec742SSukumar Swaminathan 					    qlge->received_mbx_cmds.mb[i];
349bafec742SSukumar Swaminathan 				}
350bafec742SSukumar Swaminathan 				rtn_val = DDI_SUCCESS;
351bafec742SSukumar Swaminathan 				done = 1;
352bafec742SSukumar Swaminathan 			}
353bafec742SSukumar Swaminathan 		}
354bafec742SSukumar Swaminathan 	}
355bafec742SSukumar Swaminathan err:
356bafec742SSukumar Swaminathan 	return (rtn_val);
357bafec742SSukumar Swaminathan }
358bafec742SSukumar Swaminathan 
359bafec742SSukumar Swaminathan /*
360bafec742SSukumar Swaminathan  * Inteprete incoming asynchronous events
361bafec742SSukumar Swaminathan  */
362bafec742SSukumar Swaminathan static int
ql_async_event_parser(qlge_t * qlge,mbx_data_t * mbx_cmds)363bafec742SSukumar Swaminathan ql_async_event_parser(qlge_t *qlge, mbx_data_t *mbx_cmds)
364bafec742SSukumar Swaminathan {
365bafec742SSukumar Swaminathan 	uint32_t link_status, cmd;
366bafec742SSukumar Swaminathan 	uint8_t link_speed;
367bafec742SSukumar Swaminathan 	uint8_t link_type;
368bafec742SSukumar Swaminathan 	boolean_t proc_done = B_TRUE;
369bafec742SSukumar Swaminathan 	mbx_cmd_t reply_cmd = {0};
370accf27a5SSukumar Swaminathan 	boolean_t fatal_error = B_FALSE;
371bafec742SSukumar Swaminathan 
372bafec742SSukumar Swaminathan 	switch (mbx_cmds->mb[0]) {
373bafec742SSukumar Swaminathan 	case MBA_IDC_INTERMEDIATE_COMPLETE /* 1000h */:
374bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d):"
375bafec742SSukumar Swaminathan 		    "MBA_IDC_INTERMEDIATE_COMPLETE received\n",
376bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
377bafec742SSukumar Swaminathan 		break;
378bafec742SSukumar Swaminathan 	case MBA_SYSTEM_ERR /* 8002h */:
379bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d): MBA_SYSTEM_ERR received",
380bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
381bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d): File id %x, Line # %x,"
382bafec742SSukumar Swaminathan 		    "Firmware Ver# %x",
383bafec742SSukumar Swaminathan 		    __func__, qlge->instance, mbx_cmds->mb[1],
384bafec742SSukumar Swaminathan 		    mbx_cmds->mb[2], mbx_cmds->mb[3]);
385accf27a5SSukumar Swaminathan 		fatal_error = B_TRUE;
3860662fbf4SSukumar Swaminathan 		(void) ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump);
387bafec742SSukumar Swaminathan 		break;
388bafec742SSukumar Swaminathan 	case MBA_LINK_UP /* 8011h */:
389bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n",
390bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
391bafec742SSukumar Swaminathan 		link_status = mbx_cmds->mb[1];
392bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
393bafec742SSukumar Swaminathan 		    __func__, qlge->instance, link_status));
394bafec742SSukumar Swaminathan 		link_speed = (uint8_t)((link_status >> 3) & 0x07);
395bafec742SSukumar Swaminathan 
396bafec742SSukumar Swaminathan 		if (link_speed == 0) {
397bafec742SSukumar Swaminathan 			qlge->speed = SPEED_100;
398bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n",
399bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
400bafec742SSukumar Swaminathan 		} else if (link_speed == 1) {
401bafec742SSukumar Swaminathan 			qlge->speed = SPEED_1000;
402bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n",
403bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
404bafec742SSukumar Swaminathan 		} else if (link_speed == 2) {
405bafec742SSukumar Swaminathan 			qlge->speed = SPEED_10G;
406bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n",
407bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
408bafec742SSukumar Swaminathan 			}
409bafec742SSukumar Swaminathan 
410bafec742SSukumar Swaminathan 		qlge->link_type = link_type = (uint8_t)(link_status & 0x07);
411bafec742SSukumar Swaminathan 
412bafec742SSukumar Swaminathan 		if (link_type == XFI_NETWORK_INTERFACE) {
413bafec742SSukumar Swaminathan 			/* EMPTY */
414bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
415bafec742SSukumar Swaminathan 			    ("%s(%d):Link type XFI_NETWORK_INTERFACE\n",
416bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
417bafec742SSukumar Swaminathan 		} else if (link_type == XAUI_NETWORK_INTERFACE) {
418bafec742SSukumar Swaminathan 			/* EMPTY */
419bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link type"
420bafec742SSukumar Swaminathan 			    "XAUI_NETWORK_INTERFACE\n",
421bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
422bafec742SSukumar Swaminathan 		} else if (link_type == XFI_BACKPLANE_INTERFACE) {
423bafec742SSukumar Swaminathan 			/* EMPTY */
424bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link type"
425bafec742SSukumar Swaminathan 			    "XFI_BACKPLANE_INTERFACE\n",
426bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
427bafec742SSukumar Swaminathan 		} else if (link_type == XAUI_BACKPLANE_INTERFACE) {
428bafec742SSukumar Swaminathan 			/* EMPTY */
429bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d):Link type "
430bafec742SSukumar Swaminathan 			    "XAUI_BACKPLANE_INTERFACE\n",
431bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
432bafec742SSukumar Swaminathan 		} else if (link_type == EXT_10GBASE_T_PHY) {
433bafec742SSukumar Swaminathan 			/* EMPTY */
434bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
435bafec742SSukumar Swaminathan 			    ("%s(%d):Link type EXT_10GBASE_T_PHY\n",
436bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
437bafec742SSukumar Swaminathan 		} else if (link_type == EXT_EXT_EDC_PHY) {
438bafec742SSukumar Swaminathan 			/* EMPTY */
439bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
440bafec742SSukumar Swaminathan 			    ("%s(%d):Link type EXT_EXT_EDC_PHY\n",
441bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
442bafec742SSukumar Swaminathan 		} else {
443bafec742SSukumar Swaminathan 			/* EMPTY */
444bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
445bafec742SSukumar Swaminathan 			    ("%s(%d):unknown Link type \n",
446bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
447bafec742SSukumar Swaminathan 		}
448accf27a5SSukumar Swaminathan 		cmn_err(CE_NOTE, "qlge(%d) mpi link up! speed %dMbps\n",
449accf27a5SSukumar Swaminathan 		    qlge->instance, qlge->speed);
450bafec742SSukumar Swaminathan 		/*
451bafec742SSukumar Swaminathan 		 * start timer if not started to delay some time then
452bafec742SSukumar Swaminathan 		 * check if link is really up or down
453bafec742SSukumar Swaminathan 		 */
454bafec742SSukumar Swaminathan 		ql_restart_timer(qlge);
455bafec742SSukumar Swaminathan 
456bafec742SSukumar Swaminathan 		break;
457bafec742SSukumar Swaminathan 	case MBA_LINK_DOWN /* 8012h */:
458bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
459bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_LINK_DOWN received\n",
460bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
461bafec742SSukumar Swaminathan 
462bafec742SSukumar Swaminathan 		link_status = mbx_cmds->mb[1];
463bafec742SSukumar Swaminathan 
464bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
465bafec742SSukumar Swaminathan 		    __func__, qlge->instance, link_status));
466bafec742SSukumar Swaminathan 		if (link_status & 0x1) {
467bafec742SSukumar Swaminathan 			/* EMPTY */
468bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n",
469bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
470bafec742SSukumar Swaminathan 		}
471bafec742SSukumar Swaminathan 		if (link_status & 0x2) {
472bafec742SSukumar Swaminathan 			/* EMPTY */
473bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
474bafec742SSukumar Swaminathan 			    ("%s(%d): Auto-Negotiation Failed \n",
475bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
476bafec742SSukumar Swaminathan 		}
477bafec742SSukumar Swaminathan 		if (link_status & 0x4) {
478bafec742SSukumar Swaminathan 			/* EMPTY */
479bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
480bafec742SSukumar Swaminathan 			    ("%s(%d): XTI-Training Failed \n",
481bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
482bafec742SSukumar Swaminathan 		}
483bafec742SSukumar Swaminathan 
484accf27a5SSukumar Swaminathan 		cmn_err(CE_NOTE, "qlge(%d) mpi link down!\n", qlge->instance);
485bafec742SSukumar Swaminathan 		ql_restart_timer(qlge);
486bafec742SSukumar Swaminathan 		break;
487bafec742SSukumar Swaminathan 	case MBA_IDC_COMPLETE /* 8100h */:
488bafec742SSukumar Swaminathan 
489bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
490bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_IDC_COMPLETE received\n",
491bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
492bafec742SSukumar Swaminathan 		cmd = mbx_cmds->mb[1];
493bafec742SSukumar Swaminathan 		if (cmd == MBC_STOP_FIRMWARE) {
494bafec742SSukumar Swaminathan 			/* EMPTY */
495bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
496bafec742SSukumar Swaminathan 			    ("%s(%d): STOP_FIRMWARE event completed\n",
497bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
498bafec742SSukumar Swaminathan 		} else if (cmd == MBC_IDC_REQUEST) {
499bafec742SSukumar Swaminathan 			/* EMPTY */
500bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
501bafec742SSukumar Swaminathan 			    ("%s(%d): IDC_REQUEST event completed\n",
502bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
503bafec742SSukumar Swaminathan 		} else if (cmd == MBC_PORT_RESET) {
504bafec742SSukumar Swaminathan 			/* EMPTY */
505bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
506bafec742SSukumar Swaminathan 			    ("%s(%d): PORT_RESET event completed\n",
507bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
508bafec742SSukumar Swaminathan 		} else if (cmd == MBC_SET_PORT_CONFIG) {
509bafec742SSukumar Swaminathan 			/* EMPTY */
510bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
511bafec742SSukumar Swaminathan 			    ("%s(%d): SET_PORT_CONFIG event "
512bafec742SSukumar Swaminathan 			    "completed\n", __func__, qlge->instance));
513bafec742SSukumar Swaminathan 		} else {
514bafec742SSukumar Swaminathan 			/* EMPTY */
515bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
516bafec742SSukumar Swaminathan 			    ("%s(%d): unknown IDC completion request"
517bafec742SSukumar Swaminathan 			    " event %x %x\n", __func__, qlge->instance,
518bafec742SSukumar Swaminathan 			    mbx_cmds->mb[1], mbx_cmds->mb[2]));
519bafec742SSukumar Swaminathan 		}
520bafec742SSukumar Swaminathan 		proc_done = B_FALSE;
521bafec742SSukumar Swaminathan 		break;
522bafec742SSukumar Swaminathan 
523bafec742SSukumar Swaminathan 	case MBA_IDC_REQUEST_NOTIFICATION /* 8101h */:
524bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
525bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_IDC_REQUEST_NOTIFICATION "
526bafec742SSukumar Swaminathan 		    "received\n", __func__, qlge->instance));
527bafec742SSukumar Swaminathan 		cmd = mbx_cmds->mb[1];
528bafec742SSukumar Swaminathan 		if (cmd == MBC_STOP_FIRMWARE) {
529bafec742SSukumar Swaminathan 			/* EMPTY */
530bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
531bafec742SSukumar Swaminathan 			    ("%s(%d): STOP_FIRMWARE notification"
532bafec742SSukumar Swaminathan 			    " received\n", __func__, qlge->instance));
533bafec742SSukumar Swaminathan 		} else if (cmd == MBC_IDC_REQUEST) {
534bafec742SSukumar Swaminathan 			/* EMPTY */
535bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
536bafec742SSukumar Swaminathan 			    ("%s(%d): IDC_REQUEST notification "
537bafec742SSukumar Swaminathan 			    "received\n", __func__, qlge->instance));
538bafec742SSukumar Swaminathan 		} else if (cmd == MBC_PORT_RESET) {
539bafec742SSukumar Swaminathan 			/* EMPTY */
540bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d): PORT_RESET "
541bafec742SSukumar Swaminathan 			    "notification received\n",
542bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
543bafec742SSukumar Swaminathan 		} else if (cmd == MBC_SET_PORT_CONFIG) {
544bafec742SSukumar Swaminathan 			/* EMPTY */
545bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
546bafec742SSukumar Swaminathan 			    ("%s(%d): SET_PORT_CONFIG notification "
547bafec742SSukumar Swaminathan 			    "received\n", __func__, qlge->instance));
548bafec742SSukumar Swaminathan 		} else {
549bafec742SSukumar Swaminathan 			/* EMPTY */
550bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d): "
551bafec742SSukumar Swaminathan 			    "unknown request received %x %x\n",
552bafec742SSukumar Swaminathan 			    __func__, qlge->instance, mbx_cmds->mb[1],
553bafec742SSukumar Swaminathan 			    mbx_cmds->mb[2]));
554bafec742SSukumar Swaminathan 		}
555bafec742SSukumar Swaminathan 		reply_cmd.mb[0] = MBC_IDC_ACK;
556bafec742SSukumar Swaminathan 		reply_cmd.mb[1] = mbx_cmds->mb[1];
557bafec742SSukumar Swaminathan 		reply_cmd.mb[2] = mbx_cmds->mb[2];
558bafec742SSukumar Swaminathan 		reply_cmd.mb[3] = mbx_cmds->mb[3];
559bafec742SSukumar Swaminathan 		reply_cmd.mb[4] = mbx_cmds->mb[4];
560bafec742SSukumar Swaminathan 		if (ql_issue_mailbox_cmd(qlge, &reply_cmd)
561bafec742SSukumar Swaminathan 		    != DDI_SUCCESS) {
562bafec742SSukumar Swaminathan 			cmn_err(CE_WARN,
563bafec742SSukumar Swaminathan 			    "%s(%d) send IDC Ack failed.",
564bafec742SSukumar Swaminathan 			    __func__, qlge->instance);
565bafec742SSukumar Swaminathan 		}
566bafec742SSukumar Swaminathan 		/*
567bafec742SSukumar Swaminathan 		 * verify if the incoming outbound mailbox value is what
568bafec742SSukumar Swaminathan 		 * we just sent
569bafec742SSukumar Swaminathan 		 */
570bafec742SSukumar Swaminathan 		if (mbx_cmds->mb[0] == MBS_COMMAND_COMPLETE) {
571bafec742SSukumar Swaminathan 			/* 0x4000 */
572bafec742SSukumar Swaminathan 			/* EMPTY */
573bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
574bafec742SSukumar Swaminathan 			    ("%s(%d): IDC Ack sent success.\n",
575bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
576bafec742SSukumar Swaminathan 			} else {
577bafec742SSukumar Swaminathan 			/* EMPTY */
578bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
579bafec742SSukumar Swaminathan 			    ("%s(%d): IDC Ack reply error %x %x %x.\n",
580bafec742SSukumar Swaminathan 			    __func__, qlge->instance, mbx_cmds->mb[0],
581bafec742SSukumar Swaminathan 			    mbx_cmds->mb[1], mbx_cmds->mb[2]));
582bafec742SSukumar Swaminathan 			}
583bafec742SSukumar Swaminathan 		break;
584bafec742SSukumar Swaminathan 	case MBA_IDC_TIME_EXTENDED /* 8102 */:
585bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
586bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_IDC_TIME_EXTENDED received\n",
587bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
588bafec742SSukumar Swaminathan 		break;
589bafec742SSukumar Swaminathan 	case MBA_DCBX_CONFIG_CHANGE /* 8110 */:
590bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
591bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n",
592bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
593bafec742SSukumar Swaminathan 		break;
594bafec742SSukumar Swaminathan 	case MBA_NOTIFICATION_LOST /* 8120 */:
595bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
596bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_NOTIFICATION_LOST received\n",
597bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
598bafec742SSukumar Swaminathan 		break;
599bafec742SSukumar Swaminathan 	case MBA_SFT_TRANSCEIVER_INSERTION /* 8130 */:
600bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
601bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION "
602bafec742SSukumar Swaminathan 		    "received\n", __func__, qlge->instance));
603bafec742SSukumar Swaminathan 		break;
604bafec742SSukumar Swaminathan 	case MBA_SFT_TRANSCEIVER_REMOVAL /* 8140 */:
605bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
606bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL "
607bafec742SSukumar Swaminathan 		    "received\n", __func__, qlge->instance));
608bafec742SSukumar Swaminathan 		break;
609bafec742SSukumar Swaminathan 	case MBA_FIRMWARE_INIT_COMPLETE /* 8400 */:
610bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
611bafec742SSukumar Swaminathan 		    ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE "
612bafec742SSukumar Swaminathan 		    "received\n", __func__, qlge->instance));
613bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
614bafec742SSukumar Swaminathan 		    ("%s(%d): mbx[1] %x, mbx[2] %x\n", __func__,
615bafec742SSukumar Swaminathan 		    qlge->instance, mbx_cmds->mb[1], mbx_cmds->mb[2]));
616bafec742SSukumar Swaminathan 		qlge->fw_init_complete = B_TRUE;
617bafec742SSukumar Swaminathan 		qlge->fw_version_info.major_version =
618bafec742SSukumar Swaminathan 		    LSB(MSW(mbx_cmds->mb[1]));
619bafec742SSukumar Swaminathan 		qlge->fw_version_info.minor_version =
620bafec742SSukumar Swaminathan 		    MSB(LSW(mbx_cmds->mb[1]));
621bafec742SSukumar Swaminathan 		qlge->fw_version_info.sub_minor_version =
622bafec742SSukumar Swaminathan 		    LSB(LSW(mbx_cmds->mb[1]));
623bafec742SSukumar Swaminathan 		qlge->phy_version_info.major_version =
624bafec742SSukumar Swaminathan 		    LSB(MSW(mbx_cmds->mb[2]));
625bafec742SSukumar Swaminathan 		qlge->phy_version_info.minor_version =
626bafec742SSukumar Swaminathan 		    MSB(LSW(mbx_cmds->mb[2]));
627bafec742SSukumar Swaminathan 		qlge->phy_version_info.sub_minor_version =
628bafec742SSukumar Swaminathan 		    LSB(LSW(mbx_cmds->mb[2]));
629bafec742SSukumar Swaminathan 		break;
630bafec742SSukumar Swaminathan 	case MBA_FIRMWARE_INIT_FAILED /* 8401 */:
631bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d):"
632bafec742SSukumar Swaminathan 		    "ASYNC_EVENT_FIRMWARE_INIT_FAILURE "
633bafec742SSukumar Swaminathan 		    "received:  mbx[1] %x, mbx[2] %x",
634bafec742SSukumar Swaminathan 		    __func__, qlge->instance,
635bafec742SSukumar Swaminathan 		    mbx_cmds->mb[1], mbx_cmds->mb[2]);
636accf27a5SSukumar Swaminathan 		fatal_error = B_TRUE;
637bafec742SSukumar Swaminathan 		break;
638bafec742SSukumar Swaminathan 	default:
639bafec742SSukumar Swaminathan 		if (mbx_cmds->mb[0] > 0x8000) {
640bafec742SSukumar Swaminathan 			cmn_err(CE_WARN, "%s(%d): "
641bafec742SSukumar Swaminathan 			    "Unknown Async event received: mbx[0] %x ,"
642bafec742SSukumar Swaminathan 			    "mbx[1] %x; mbx[2] %x",
643bafec742SSukumar Swaminathan 			    __func__, qlge->instance,
644bafec742SSukumar Swaminathan 			    mbx_cmds->mb[0], mbx_cmds->mb[1],
645bafec742SSukumar Swaminathan 			    mbx_cmds->mb[2]);
646bafec742SSukumar Swaminathan 			proc_done = B_TRUE;
647bafec742SSukumar Swaminathan 		} else {
648bafec742SSukumar Swaminathan 			proc_done = B_FALSE;
649bafec742SSukumar Swaminathan 		}
650bafec742SSukumar Swaminathan 		break;
651bafec742SSukumar Swaminathan 	}
652accf27a5SSukumar Swaminathan 	if (fatal_error) {
653accf27a5SSukumar Swaminathan 		if (qlge->fm_enable) {
654accf27a5SSukumar Swaminathan 			ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
655accf27a5SSukumar Swaminathan 			ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
656accf27a5SSukumar Swaminathan 			atomic_or_32(&qlge->flags, ADAPTER_ERROR);
657accf27a5SSukumar Swaminathan 		}
658accf27a5SSukumar Swaminathan 	}
659bafec742SSukumar Swaminathan 	return (proc_done);
660bafec742SSukumar Swaminathan }
661bafec742SSukumar Swaminathan 
662bafec742SSukumar Swaminathan 
663bafec742SSukumar Swaminathan /*
664bafec742SSukumar Swaminathan  * MPI Interrupt handler
665bafec742SSukumar Swaminathan  * Caller must have MBX_LOCK
666bafec742SSukumar Swaminathan  */
667bafec742SSukumar Swaminathan void
ql_do_mpi_intr(qlge_t * qlge)668bafec742SSukumar Swaminathan ql_do_mpi_intr(qlge_t *qlge)
669bafec742SSukumar Swaminathan {
670bafec742SSukumar Swaminathan 	/*
671bafec742SSukumar Swaminathan 	 * we just need to read first few mailboxes that this adapter's MPI
672bafec742SSukumar Swaminathan 	 * will write response to.
673bafec742SSukumar Swaminathan 	 */
674bafec742SSukumar Swaminathan 	mutex_enter(&qlge->mbx_mutex);
675bafec742SSukumar Swaminathan 
6760662fbf4SSukumar Swaminathan 	(void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds,
6770662fbf4SSukumar Swaminathan 	    qlge->max_read_mbx);
678bafec742SSukumar Swaminathan 
679bafec742SSukumar Swaminathan 	/*
680bafec742SSukumar Swaminathan 	 * process PI interrupt as async events, if not done,
681bafec742SSukumar Swaminathan 	 * then pass to mailbox processing
682bafec742SSukumar Swaminathan 	 */
683bafec742SSukumar Swaminathan 	if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) {
684bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n",
685bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
686bafec742SSukumar Swaminathan 		/*
687bafec742SSukumar Swaminathan 		 * If another thread is waiting for the mail box
688bafec742SSukumar Swaminathan 		 * completion event to occur
689bafec742SSukumar Swaminathan 		 */
690bafec742SSukumar Swaminathan 		if (qlge->mbx_wait_completion == 1) {
691bafec742SSukumar Swaminathan 			qlge->mbx_wait_completion = 0;
692bafec742SSukumar Swaminathan 			cv_broadcast(&qlge->cv_mbx_intr);
693bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX,
694bafec742SSukumar Swaminathan 			    ("%s(%d) mailbox completion signaled \n",
695bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
696bafec742SSukumar Swaminathan 		}
697bafec742SSukumar Swaminathan 	}
698bafec742SSukumar Swaminathan 	/* inform MPI Firmware to clear the interrupt */
699bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_HOST_CMD_STATUS,
700bafec742SSukumar Swaminathan 	    HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */);
701bafec742SSukumar Swaminathan 	mutex_exit(&qlge->mbx_mutex);
702bafec742SSukumar Swaminathan 	ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */
703bafec742SSukumar Swaminathan }
704bafec742SSukumar Swaminathan 
705bafec742SSukumar Swaminathan /*
706bafec742SSukumar Swaminathan  * Test if mailbox communication works
707bafec742SSukumar Swaminathan  * This is used when Interrupt is not enabled
708bafec742SSukumar Swaminathan  */
709bafec742SSukumar Swaminathan int
ql_mbx_test(qlge_t * qlge)710bafec742SSukumar Swaminathan ql_mbx_test(qlge_t *qlge)
711bafec742SSukumar Swaminathan {
712bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds;
713bafec742SSukumar Swaminathan 	mbx_data_t mbx_results;
714bafec742SSukumar Swaminathan 	int i, test_ok = 1;
715bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
716bafec742SSukumar Swaminathan 
717bafec742SSukumar Swaminathan 	for (i = 0; i < NUM_MAILBOX_REGS; i++)
718bafec742SSukumar Swaminathan 		mbx_cmds.mb[i] = i;
719bafec742SSukumar Swaminathan 
720bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
721bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
722bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
723bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
724bafec742SSukumar Swaminathan 		goto out;
725bafec742SSukumar Swaminathan 	}
726bafec742SSukumar Swaminathan 
727bafec742SSukumar Swaminathan 	/* delay for the processor interrupt is received */
728bafec742SSukumar Swaminathan 	if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout)
729bafec742SSukumar Swaminathan 	    == DDI_SUCCESS) {
730bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
731bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
7320662fbf4SSukumar Swaminathan 		(void) ql_read_mailbox_cmd(qlge, &mbx_results, 0);
733bafec742SSukumar Swaminathan 
734bafec742SSukumar Swaminathan 		ql_write_reg(qlge, REG_HOST_CMD_STATUS,
735bafec742SSukumar Swaminathan 		    HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
736bafec742SSukumar Swaminathan 
737bafec742SSukumar Swaminathan 		if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
738bafec742SSukumar Swaminathan 			test_ok = 0;
739bafec742SSukumar Swaminathan 		} else {
740bafec742SSukumar Swaminathan 			for (i = 1; i < NUM_MAILBOX_REGS; i++) {
741bafec742SSukumar Swaminathan 				if (mbx_results.mb[i] != i) {
742bafec742SSukumar Swaminathan 					test_ok = 0;
743bafec742SSukumar Swaminathan 					break;
744bafec742SSukumar Swaminathan 				}
745bafec742SSukumar Swaminathan 			}
746bafec742SSukumar Swaminathan 		}
747bafec742SSukumar Swaminathan 		if (test_ok) {
748bafec742SSukumar Swaminathan 			rtn_val = DDI_SUCCESS;
749bafec742SSukumar Swaminathan 		} else {
750bafec742SSukumar Swaminathan 			cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
751bafec742SSukumar Swaminathan 			    __func__, qlge->instance);
752bafec742SSukumar Swaminathan 		}
753bafec742SSukumar Swaminathan 	} else {
754bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) mailbox testing error: "
755bafec742SSukumar Swaminathan 		    "PI Intr not received ", __func__, qlge->instance);
756bafec742SSukumar Swaminathan 	}
757bafec742SSukumar Swaminathan out:
758bafec742SSukumar Swaminathan 	return (rtn_val);
759bafec742SSukumar Swaminathan }
760bafec742SSukumar Swaminathan 
761bafec742SSukumar Swaminathan /*
762bafec742SSukumar Swaminathan  * ql_mbx_test2
763bafec742SSukumar Swaminathan  * Test if mailbox communication works
764bafec742SSukumar Swaminathan  * This is used when Interrupt is enabled
765bafec742SSukumar Swaminathan  * mailbox cmd:0x06h
766bafec742SSukumar Swaminathan  */
767bafec742SSukumar Swaminathan int
ql_mbx_test2(qlge_t * qlge)768bafec742SSukumar Swaminathan ql_mbx_test2(qlge_t *qlge)
769bafec742SSukumar Swaminathan {
770bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
771bafec742SSukumar Swaminathan 	int i, test_ok = 1;
772bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
773bafec742SSukumar Swaminathan 
774bafec742SSukumar Swaminathan 	for (i = 0; i < NUM_MAILBOX_REGS; i++)
775bafec742SSukumar Swaminathan 		mbx_cmds.mb[i] = i;
776bafec742SSukumar Swaminathan 
777bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
778bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
779bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
780bafec742SSukumar Swaminathan 		    "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
781bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
782bafec742SSukumar Swaminathan 		goto out;
783bafec742SSukumar Swaminathan 	}
784bafec742SSukumar Swaminathan 
785bafec742SSukumar Swaminathan 	/* verify if the incoming outbound mailbox value is what we just sent */
786bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
787bafec742SSukumar Swaminathan 		test_ok = 0;
788bafec742SSukumar Swaminathan 	} else {
789bafec742SSukumar Swaminathan 		for (i = 1; i < qlge->max_read_mbx; i++) {
790bafec742SSukumar Swaminathan 			if (mbx_cmds.mb[i] != i) {
791bafec742SSukumar Swaminathan 				test_ok = 0;
792bafec742SSukumar Swaminathan 				break;
793bafec742SSukumar Swaminathan 			}
794bafec742SSukumar Swaminathan 		}
795bafec742SSukumar Swaminathan 	}
796bafec742SSukumar Swaminathan 	if (test_ok) {
797bafec742SSukumar Swaminathan 		rtn_val = DDI_SUCCESS;
798bafec742SSukumar Swaminathan 	} else {
799bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
800bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
801bafec742SSukumar Swaminathan 	}
802bafec742SSukumar Swaminathan out:
803accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
804accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
805accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
806accf27a5SSukumar Swaminathan 	}
807bafec742SSukumar Swaminathan 	return (rtn_val);
808bafec742SSukumar Swaminathan }
809bafec742SSukumar Swaminathan 
810bafec742SSukumar Swaminathan /*
811bafec742SSukumar Swaminathan  * ql_get_fw_state
812bafec742SSukumar Swaminathan  * Get fw state.
813bafec742SSukumar Swaminathan  * mailbox cmd:0x69h
814bafec742SSukumar Swaminathan  */
815bafec742SSukumar Swaminathan int
ql_get_fw_state(qlge_t * qlge,uint32_t * fw_state_ptr)816bafec742SSukumar Swaminathan ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr)
817bafec742SSukumar Swaminathan {
818bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
819bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
820bafec742SSukumar Swaminathan 
821bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE;
822bafec742SSukumar Swaminathan 
823bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
824bafec742SSukumar Swaminathan 	    != DDI_SUCCESS) {
825bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
826bafec742SSukumar Swaminathan 		    " failed.", __func__, qlge->instance);
827bafec742SSukumar Swaminathan 		goto out;
828bafec742SSukumar Swaminathan 	}
829bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successful */
830bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
831bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) failed, 0x%x",
832bafec742SSukumar Swaminathan 		    __func__, qlge->instance, mbx_cmds.mb[0]);
833bafec742SSukumar Swaminathan 	} else {
834bafec742SSukumar Swaminathan 		/* EMPTY */
835bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1]));
836bafec742SSukumar Swaminathan 	}
837bafec742SSukumar Swaminathan 	if (fw_state_ptr != NULL)
838bafec742SSukumar Swaminathan 		*fw_state_ptr = mbx_cmds.mb[1];
839bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
840bafec742SSukumar Swaminathan out:
841accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
842accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
843accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
844accf27a5SSukumar Swaminathan 	}
845bafec742SSukumar Swaminathan 	return (rtn_val);
846bafec742SSukumar Swaminathan }
847bafec742SSukumar Swaminathan 
848bafec742SSukumar Swaminathan /*
849bafec742SSukumar Swaminathan  * ql_set_IDC_Req
850bafec742SSukumar Swaminathan  * Send a IDC Request to firmware to notify all functions
851bafec742SSukumar Swaminathan  * or any specific functions on the same port
852bafec742SSukumar Swaminathan  * mailbox cmd:0x100h
853bafec742SSukumar Swaminathan  */
854bafec742SSukumar Swaminathan int
ql_set_IDC_Req(qlge_t * qlge,uint8_t dest_functions,uint8_t timeout)855bafec742SSukumar Swaminathan ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout)
856bafec742SSukumar Swaminathan {
857bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
858bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
859bafec742SSukumar Swaminathan 
860bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */;
861bafec742SSukumar Swaminathan 	mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number;
862bafec742SSukumar Swaminathan 
863bafec742SSukumar Swaminathan 	switch (dest_functions) {
864bafec742SSukumar Swaminathan 	case IDC_REQ_DEST_FUNC_ALL:
865bafec742SSukumar Swaminathan 		mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK;
866bafec742SSukumar Swaminathan 		mbx_cmds.mb[2] = 0;
867bafec742SSukumar Swaminathan 		break;
868bafec742SSukumar Swaminathan 	case IDC_REQ_DEST_FUNC_0:
869bafec742SSukumar Swaminathan 		mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK;
870bafec742SSukumar Swaminathan 		break;
871bafec742SSukumar Swaminathan 	case IDC_REQ_DEST_FUNC_1:
872bafec742SSukumar Swaminathan 		mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK;
873bafec742SSukumar Swaminathan 		break;
874bafec742SSukumar Swaminathan 	case IDC_REQ_DEST_FUNC_2:
875bafec742SSukumar Swaminathan 		mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK;
876bafec742SSukumar Swaminathan 		break;
877bafec742SSukumar Swaminathan 	case IDC_REQ_DEST_FUNC_3:
878bafec742SSukumar Swaminathan 		mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK;
879bafec742SSukumar Swaminathan 		break;
880bafec742SSukumar Swaminathan 	default:
881bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "Wrong dest functions %x",
882bafec742SSukumar Swaminathan 		    dest_functions);
883bafec742SSukumar Swaminathan 	}
884bafec742SSukumar Swaminathan 
885bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
886bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
887bafec742SSukumar Swaminathan 		    "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
888bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
889bafec742SSukumar Swaminathan 		goto out;
890bafec742SSukumar Swaminathan 	}
891bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successful */
892bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) {
893bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n",
894bafec742SSukumar Swaminathan 		    __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2]));
895bafec742SSukumar Swaminathan 		rtn_val = DDI_SUCCESS;
896bafec742SSukumar Swaminathan 	} else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
897bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n",
898bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
899bafec742SSukumar Swaminathan 		rtn_val = DDI_SUCCESS;
900bafec742SSukumar Swaminathan 	} else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) {
901bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR",
902bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
903bafec742SSukumar Swaminathan 	} else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) {
904bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR",
905bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
906bafec742SSukumar Swaminathan 	} else {
907bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:"
908bafec742SSukumar Swaminathan 		    " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance,
909bafec742SSukumar Swaminathan 		    mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]);
910bafec742SSukumar Swaminathan 	}
911bafec742SSukumar Swaminathan 
912bafec742SSukumar Swaminathan out:
913accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
914accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
915accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
916accf27a5SSukumar Swaminathan 	}
917accf27a5SSukumar Swaminathan return (rtn_val);
918bafec742SSukumar Swaminathan }
919bafec742SSukumar Swaminathan 
920bafec742SSukumar Swaminathan /*
921bafec742SSukumar Swaminathan  * ql_set_mpi_port_config
922bafec742SSukumar Swaminathan  * Send new port configuration.to mpi
923bafec742SSukumar Swaminathan  * mailbox cmd:0x122h
924bafec742SSukumar Swaminathan  */
925accf27a5SSukumar Swaminathan int
ql_set_mpi_port_config(qlge_t * qlge,port_cfg_info_t new_cfg)926bafec742SSukumar Swaminathan ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg)
927bafec742SSukumar Swaminathan {
928bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
929bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
930bafec742SSukumar Swaminathan 
931bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */;
932bafec742SSukumar Swaminathan 	mbx_cmds.mb[1] = new_cfg.link_cfg;
933bafec742SSukumar Swaminathan 	mbx_cmds.mb[2] = new_cfg.max_frame_size;
934bafec742SSukumar Swaminathan 
935bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
936bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
937bafec742SSukumar Swaminathan 		    " failed.", __func__, qlge->instance);
938bafec742SSukumar Swaminathan 		goto out;
939bafec742SSukumar Swaminathan 	}
940bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successful */
941bafec742SSukumar Swaminathan 	if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) &&
942bafec742SSukumar Swaminathan 	    (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) {
943accf27a5SSukumar Swaminathan 		cmn_err(CE_WARN, "set port config (%d) failed, 0x%x",
944accf27a5SSukumar Swaminathan 		    qlge->instance, mbx_cmds.mb[0]);
945bafec742SSukumar Swaminathan 	} else
946bafec742SSukumar Swaminathan 		rtn_val = DDI_SUCCESS;
947bafec742SSukumar Swaminathan out:
948accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
949accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
950accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
951accf27a5SSukumar Swaminathan 	}
952bafec742SSukumar Swaminathan 	return (rtn_val);
953bafec742SSukumar Swaminathan }
954bafec742SSukumar Swaminathan 
955bafec742SSukumar Swaminathan int
ql_set_pause_mode(qlge_t * qlge)956accf27a5SSukumar Swaminathan ql_set_pause_mode(qlge_t *qlge)
957bafec742SSukumar Swaminathan {
958bafec742SSukumar Swaminathan 	uint32_t pause_bit_mask = 0x60;	/* bit 5-6 */
959bafec742SSukumar Swaminathan 
960bafec742SSukumar Swaminathan 	/* clear pause bits */
961bafec742SSukumar Swaminathan 	qlge->port_cfg_info.link_cfg &= ~pause_bit_mask;
962accf27a5SSukumar Swaminathan 
963bafec742SSukumar Swaminathan 	/* set new pause mode */
964bafec742SSukumar Swaminathan 	if (qlge->pause == PAUSE_MODE_STANDARD)
965bafec742SSukumar Swaminathan 		qlge->port_cfg_info.link_cfg |= STD_PAUSE;
966bafec742SSukumar Swaminathan 	else if (qlge->pause == PAUSE_MODE_PER_PRIORITY)
967bafec742SSukumar Swaminathan 		qlge->port_cfg_info.link_cfg |= PP_PAUSE;
968bafec742SSukumar Swaminathan 
969accf27a5SSukumar Swaminathan 	return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
970accf27a5SSukumar Swaminathan }
971accf27a5SSukumar Swaminathan 
972accf27a5SSukumar Swaminathan int
ql_set_loop_back_mode(qlge_t * qlge)973accf27a5SSukumar Swaminathan ql_set_loop_back_mode(qlge_t *qlge)
974accf27a5SSukumar Swaminathan {
975accf27a5SSukumar Swaminathan 	uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */
976accf27a5SSukumar Swaminathan 
977accf27a5SSukumar Swaminathan 	/* clear loop back bits */
978accf27a5SSukumar Swaminathan 	qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask;
979bafec742SSukumar Swaminathan 	/* loop back cfg: bit1-3 */
980bafec742SSukumar Swaminathan 	if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL)
981bafec742SSukumar Swaminathan 		qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL;
982bafec742SSukumar Swaminathan 	else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL)
983bafec742SSukumar Swaminathan 		qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL;
984*cddcb3daSSukumar Swaminathan 	else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY)
985*cddcb3daSSukumar Swaminathan 		qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY;
986bafec742SSukumar Swaminathan 
987bafec742SSukumar Swaminathan 	return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
988bafec742SSukumar Swaminathan 
989bafec742SSukumar Swaminathan }
990bafec742SSukumar Swaminathan /*
991bafec742SSukumar Swaminathan  * ql_get_port_cfg
992bafec742SSukumar Swaminathan  * Get port configuration.
993bafec742SSukumar Swaminathan  * mailbox cmd:0x123h
994bafec742SSukumar Swaminathan  */
995bafec742SSukumar Swaminathan int
ql_get_port_cfg(qlge_t * qlge)996bafec742SSukumar Swaminathan ql_get_port_cfg(qlge_t *qlge)
997bafec742SSukumar Swaminathan {
998bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
999bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
1000bafec742SSukumar Swaminathan 
1001bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */;
1002bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
1003bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
1004bafec742SSukumar Swaminathan 		    " failed.", __func__, qlge->instance);
1005bafec742SSukumar Swaminathan 		goto out;
1006bafec742SSukumar Swaminathan 	}
1007bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successfully */
1008bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1009accf27a5SSukumar Swaminathan 		cmn_err(CE_WARN, "get port config (%d) failed, 0x%x",
1010accf27a5SSukumar Swaminathan 		    qlge->instance, mbx_cmds.mb[0]);
1011bafec742SSukumar Swaminathan 	} else { /* verify frame size */
1012bafec742SSukumar Swaminathan 		if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) ||
1013bafec742SSukumar Swaminathan 		    (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) {
1014bafec742SSukumar Swaminathan 			qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1];
1015bafec742SSukumar Swaminathan 			qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2];
1016bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:"
1017bafec742SSukumar Swaminathan 			    " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2]));
1018bafec742SSukumar Swaminathan 			rtn_val = DDI_SUCCESS;
1019bafec742SSukumar Swaminathan 		} else {
1020bafec742SSukumar Swaminathan 			cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:"
1021bafec742SSukumar Swaminathan 			    " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]);
1022bafec742SSukumar Swaminathan 		}
1023bafec742SSukumar Swaminathan 	}
1024bafec742SSukumar Swaminathan out:
1025accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1026accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1027accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1028accf27a5SSukumar Swaminathan 	}
1029bafec742SSukumar Swaminathan 	return (rtn_val);
1030bafec742SSukumar Swaminathan }
1031bafec742SSukumar Swaminathan 
1032bafec742SSukumar Swaminathan /*
1033bafec742SSukumar Swaminathan  * qlge_get_link_status
1034bafec742SSukumar Swaminathan  * Get link status.
1035bafec742SSukumar Swaminathan  * mailbox cmd:0x124h
1036bafec742SSukumar Swaminathan  */
1037bafec742SSukumar Swaminathan int
qlge_get_link_status(qlge_t * qlge,struct qlnic_link_status_info * link_status_ptr)1038bafec742SSukumar Swaminathan qlge_get_link_status(qlge_t *qlge,
1039bafec742SSukumar Swaminathan     struct qlnic_link_status_info *link_status_ptr)
1040bafec742SSukumar Swaminathan {
1041bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
1042bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
1043bafec742SSukumar Swaminathan 
1044bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */;
1045bafec742SSukumar Swaminathan 
1046bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
1047bafec742SSukumar Swaminathan 	    != DDI_SUCCESS) {
1048bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
1049bafec742SSukumar Swaminathan 		    "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1050bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
1051bafec742SSukumar Swaminathan 		goto out;
1052bafec742SSukumar Swaminathan 	}
1053bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successful */
1054bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1055accf27a5SSukumar Swaminathan 		cmn_err(CE_WARN, "get link status(%d) failed, 0x%x",
1056bafec742SSukumar Swaminathan 		    qlge->instance, mbx_cmds.mb[0]);
1057bafec742SSukumar Swaminathan 	} else {
1058bafec742SSukumar Swaminathan 		/* EMPTY */
1059bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX,
1060bafec742SSukumar Swaminathan 		    ("link status: status1 : 0x%x, status2 : 0x%x, "
1061bafec742SSukumar Swaminathan 		    "status3 : 0x%x\n",
1062bafec742SSukumar Swaminathan 		    mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3]));
1063bafec742SSukumar Swaminathan 	}
1064bafec742SSukumar Swaminathan 	if (link_status_ptr != NULL) {
1065bafec742SSukumar Swaminathan 		link_status_ptr->link_status_info = mbx_cmds.mb[1];
1066bafec742SSukumar Swaminathan 		link_status_ptr->additional_info = mbx_cmds.mb[2];
1067bafec742SSukumar Swaminathan 		link_status_ptr->network_hw_info = mbx_cmds.mb[3];
1068bafec742SSukumar Swaminathan 		link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4];
1069bafec742SSukumar Swaminathan 		link_status_ptr->change_counters_info = mbx_cmds.mb[5];
1070bafec742SSukumar Swaminathan 	}
1071bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
1072bafec742SSukumar Swaminathan out:
1073accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1074accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1075accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1076accf27a5SSukumar Swaminathan 	}
1077bafec742SSukumar Swaminathan 	return (rtn_val);
1078bafec742SSukumar Swaminathan }
1079bafec742SSukumar Swaminathan 
1080bafec742SSukumar Swaminathan /*
1081bafec742SSukumar Swaminathan  * ql_get_firmware_version
1082bafec742SSukumar Swaminathan  * Get firmware version.
1083bafec742SSukumar Swaminathan  */
1084bafec742SSukumar Swaminathan int
ql_get_firmware_version(qlge_t * qlge,struct qlnic_mpi_version_info * mpi_version_ptr)1085bafec742SSukumar Swaminathan ql_get_firmware_version(qlge_t *qlge,
1086bafec742SSukumar Swaminathan     struct qlnic_mpi_version_info *mpi_version_ptr)
1087bafec742SSukumar Swaminathan {
1088bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
1089bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
1090bafec742SSukumar Swaminathan 
1091bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */;
1092bafec742SSukumar Swaminathan 
1093bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
1094bafec742SSukumar Swaminathan 	    != DDI_SUCCESS) {
1095bafec742SSukumar Swaminathan 		cmn_err(CE_WARN,
1096bafec742SSukumar Swaminathan 		    "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1097bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
1098bafec742SSukumar Swaminathan 		goto out;
1099bafec742SSukumar Swaminathan 	}
1100bafec742SSukumar Swaminathan 
1101bafec742SSukumar Swaminathan 	/* verify if the transaction is completed successful */
1102bafec742SSukumar Swaminathan 	if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
1103accf27a5SSukumar Swaminathan 		cmn_err(CE_WARN, "get firmware version(%d) failed, 0x%x",
1104bafec742SSukumar Swaminathan 		    qlge->instance, mbx_cmds.mb[0]);
1105bafec742SSukumar Swaminathan 	} else {
1106bafec742SSukumar Swaminathan 		qlge->fw_version_info.major_version =
1107bafec742SSukumar Swaminathan 		    LSB(MSW(mbx_cmds.mb[1]));
1108bafec742SSukumar Swaminathan 		qlge->fw_version_info.minor_version =
1109bafec742SSukumar Swaminathan 		    MSB(LSW(mbx_cmds.mb[1]));
1110bafec742SSukumar Swaminathan 		qlge->fw_version_info.sub_minor_version =
1111bafec742SSukumar Swaminathan 		    LSB(LSW(mbx_cmds.mb[1]));
1112bafec742SSukumar Swaminathan 		qlge->phy_version_info.major_version =
1113bafec742SSukumar Swaminathan 		    LSB(MSW(mbx_cmds.mb[2]));
1114bafec742SSukumar Swaminathan 		qlge->phy_version_info.minor_version =
1115bafec742SSukumar Swaminathan 		    MSB(LSW(mbx_cmds.mb[2]));
1116bafec742SSukumar Swaminathan 		qlge->phy_version_info.sub_minor_version =
1117bafec742SSukumar Swaminathan 		    LSB(LSW(mbx_cmds.mb[2]));
1118bafec742SSukumar Swaminathan #ifdef QLGE_LOAD_UNLOAD
1119bafec742SSukumar Swaminathan 		cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n",
1120bafec742SSukumar Swaminathan 		    qlge->fw_version_info.major_version,
1121bafec742SSukumar Swaminathan 		    qlge->fw_version_info.minor_version,
1122bafec742SSukumar Swaminathan 		    qlge->fw_version_info.sub_minor_version);
1123bafec742SSukumar Swaminathan #endif
1124bafec742SSukumar Swaminathan 		if (mpi_version_ptr != NULL) {
1125bafec742SSukumar Swaminathan 			mpi_version_ptr->fw_version =
1126bafec742SSukumar Swaminathan 			    (qlge->fw_version_info.major_version<<16)
1127bafec742SSukumar Swaminathan 			    |(qlge->fw_version_info.minor_version<<8)
1128bafec742SSukumar Swaminathan 			    |(qlge->fw_version_info.sub_minor_version);
1129bafec742SSukumar Swaminathan 			mpi_version_ptr->phy_version =
1130bafec742SSukumar Swaminathan 			    (qlge->phy_version_info.major_version<<16)
1131bafec742SSukumar Swaminathan 			    |(qlge->phy_version_info.minor_version<<8)
1132bafec742SSukumar Swaminathan 			    |(qlge->phy_version_info.sub_minor_version);
1133bafec742SSukumar Swaminathan 		}
1134bafec742SSukumar Swaminathan 	}
1135bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
1136bafec742SSukumar Swaminathan out:
1137accf27a5SSukumar Swaminathan 	if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
1138accf27a5SSukumar Swaminathan 		ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1139accf27a5SSukumar Swaminathan 		ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
1140accf27a5SSukumar Swaminathan 	}
1141bafec742SSukumar Swaminathan 	return (rtn_val);
1142bafec742SSukumar Swaminathan }
1143bafec742SSukumar Swaminathan 
1144bafec742SSukumar Swaminathan /*
1145bafec742SSukumar Swaminathan  * Trigger a system error event
1146bafec742SSukumar Swaminathan  */
1147bafec742SSukumar Swaminathan int
ql_trigger_system_error_event(qlge_t * qlge)1148bafec742SSukumar Swaminathan ql_trigger_system_error_event(qlge_t *qlge)
1149bafec742SSukumar Swaminathan {
1150bafec742SSukumar Swaminathan 	mbx_cmd_t mbx_cmds = {0};
1151bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
1152bafec742SSukumar Swaminathan 
1153bafec742SSukumar Swaminathan 	mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */
1154bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
1155bafec742SSukumar Swaminathan 		cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
1156bafec742SSukumar Swaminathan 		    __func__, qlge->instance);
1157bafec742SSukumar Swaminathan 		goto out;
1158bafec742SSukumar Swaminathan 	}
1159bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
1160bafec742SSukumar Swaminathan out:
1161bafec742SSukumar Swaminathan 	return (rtn_val);
1162bafec742SSukumar Swaminathan }
1163bafec742SSukumar Swaminathan 
1164bafec742SSukumar Swaminathan /*
1165bafec742SSukumar Swaminathan  * Reset the MPI RISC Processor
1166bafec742SSukumar Swaminathan  */
1167bafec742SSukumar Swaminathan int
ql_reset_mpi_risc(qlge_t * qlge)1168bafec742SSukumar Swaminathan ql_reset_mpi_risc(qlge_t *qlge)
1169bafec742SSukumar Swaminathan {
1170bafec742SSukumar Swaminathan 	int rtn_val = DDI_FAILURE;
1171bafec742SSukumar Swaminathan 
1172bafec742SSukumar Swaminathan 	/* Reset the MPI Processor */
1173bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET);
1174bafec742SSukumar Swaminathan 	if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET,
1175bafec742SSukumar Swaminathan 	    BIT_SET, 0) != DDI_SUCCESS) {
11764aa4baabSSukumar Swaminathan 		(void) ql_read_reg(qlge, REG_HOST_CMD_STATUS);
1177bafec742SSukumar Swaminathan 		goto out;
1178bafec742SSukumar Swaminathan 	}
1179bafec742SSukumar Swaminathan 	ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET);
1180bafec742SSukumar Swaminathan 	rtn_val = DDI_SUCCESS;
1181bafec742SSukumar Swaminathan out:
1182bafec742SSukumar Swaminathan 	return (rtn_val);
1183bafec742SSukumar Swaminathan }
1184bafec742SSukumar Swaminathan 
1185bafec742SSukumar Swaminathan int
ql_read_risc_ram(qlge_t * qlge,uint32_t risc_address,uint64_t bp,uint32_t word_count)1186bafec742SSukumar Swaminathan ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp,
1187bafec742SSukumar Swaminathan     uint32_t word_count)
1188bafec742SSukumar Swaminathan {
1189bafec742SSukumar Swaminathan 	int rval = DDI_FAILURE;
1190bafec742SSukumar Swaminathan 	mbx_cmd_t mc = {0};
1191bafec742SSukumar Swaminathan 	mbx_cmd_t *mcp = &mc;
1192bafec742SSukumar Swaminathan 	mbx_data_t mbx_results;
1193bafec742SSukumar Swaminathan 
1194bafec742SSukumar Swaminathan 	QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x,"
1195bafec742SSukumar Swaminathan 	    "phys_addr %x,%x words\n", __func__, qlge->instance,
1196bafec742SSukumar Swaminathan 	    risc_address, bp, word_count));
1197bafec742SSukumar Swaminathan 	if (CFG_IST(qlge, CFG_CHIP_8100)) {
1198bafec742SSukumar Swaminathan 		mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */;
1199bafec742SSukumar Swaminathan 		mcp->mb[1] = LSW(risc_address);
1200bafec742SSukumar Swaminathan 		mcp->mb[2] = MSW(LSD(bp));
1201bafec742SSukumar Swaminathan 		mcp->mb[3] = LSW(LSD(bp));
1202bafec742SSukumar Swaminathan 		mcp->mb[4] = MSW(word_count);
1203bafec742SSukumar Swaminathan 		mcp->mb[5] = LSW(word_count);
1204bafec742SSukumar Swaminathan 		mcp->mb[6] = MSW(MSD(bp));
1205bafec742SSukumar Swaminathan 		mcp->mb[7] = LSW(MSD(bp));
1206bafec742SSukumar Swaminathan 		mcp->mb[8] = MSW(risc_address);
1207bafec742SSukumar Swaminathan 	}
1208bafec742SSukumar Swaminathan 	mcp->timeout = 10 /* MAILBOX_TOV */;
1209bafec742SSukumar Swaminathan 
1210bafec742SSukumar Swaminathan 	if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results)
1211bafec742SSukumar Swaminathan 	    != DDI_SUCCESS) {
1212bafec742SSukumar Swaminathan 		goto out;
1213bafec742SSukumar Swaminathan 	} else {
1214bafec742SSukumar Swaminathan 		QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
1215bafec742SSukumar Swaminathan 		    __func__, qlge->instance));
1216bafec742SSukumar Swaminathan 		if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
1217bafec742SSukumar Swaminathan 			QL_PRINT(DBG_MBX, ("%s(%d): success\n",
1218bafec742SSukumar Swaminathan 			    __func__, qlge->instance));
1219bafec742SSukumar Swaminathan 			rval = DDI_SUCCESS;
1220bafec742SSukumar Swaminathan 		} else {
1221accf27a5SSukumar Swaminathan 			cmn_err(CE_WARN, "read_risc_ram(%d): failed, status %x",
1222accf27a5SSukumar Swaminathan 			    qlge->instance, mbx_results.mb[0]);
1223bafec742SSukumar Swaminathan 		}
1224bafec742SSukumar Swaminathan 	}
1225bafec742SSukumar Swaminathan out:
1226bafec742SSukumar Swaminathan 	return (rval);
1227bafec742SSukumar Swaminathan }
1228