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, ®_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