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