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.
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.
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]
23 * Copyright 2010 QLogic Corporation. All rights reserved.
28 static int ql_async_event_parser(qlge_t
*, mbx_data_t
*);
31 * Wait upto timeout seconds for Processor Interrupt
32 * if timeout is 0, then wait for default waittime
35 ql_poll_processor_intr(qlge_t
*qlge
, uint8_t timeout
)
37 int rtn_val
= DDI_SUCCESS
;
39 if (ql_wait_reg_bit(qlge
, REG_STATUS
, STS_PI
, BIT_SET
, timeout
)
41 cmn_err(CE_WARN
, "Polling for processor interrupt failed.");
42 rtn_val
= DDI_FAILURE
;
48 * Wait for mailbox Processor Register Ready
51 ql_wait_processor_addr_reg_ready(qlge_t
*qlge
)
53 int rtn_val
= DDI_SUCCESS
;
55 if (ql_wait_reg_bit(qlge
, REG_PROCESSOR_ADDR
,
56 PROCESSOR_ADDRESS_RDY
, BIT_SET
, 0) != DDI_SUCCESS
) {
58 "Wait for processor address register ready timeout.");
59 rtn_val
= DDI_FAILURE
;
65 * Read and write MPI registers using the indirect register interface
66 * Assume all the locks&semaphore have been acquired
69 ql_write_processor_data(qlge_t
*qlge
, uint32_t addr
, uint32_t data
)
71 int rtn_val
= DDI_FAILURE
;
73 /* wait for processor address register ready */
74 if (ql_wait_processor_addr_reg_ready(qlge
) == DDI_FAILURE
)
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
)
84 rtn_val
= DDI_SUCCESS
;
92 * Read from processor register
95 ql_read_processor_data(qlge_t
*qlge
, uint32_t addr
, uint32_t *data
)
97 int rtn_val
= DDI_FAILURE
;
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
)
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
)
111 *data
= ql_read_reg(qlge
, REG_PROCESSOR_DATA
);
113 rtn_val
= DDI_SUCCESS
;
121 * Read "count" number of outgoing Mailbox register starting
122 * from mailbox #0 if count is 0 then read all mailboxes
125 ql_read_mailbox_cmd(qlge_t
*qlge
, mbx_data_t
*mbx_buf
, uint32_t count
)
127 int rtn_val
= DDI_FAILURE
;
132 if (ql_sem_spinlock(qlge
, QL_PROCESSOR_SEM_MASK
) != DDI_SUCCESS
) {
134 "%s(%d) get QL_PROCESSOR_SEM_MASK time out error",
135 __func__
, qlge
->instance
);
136 return (DDI_FAILURE
);
139 if (qlge
->func_number
== qlge
->fn0_net
)
140 addr
= FUNC_0_OUT_MAILBOX_0_REG_OFFSET
;
142 addr
= FUNC_1_OUT_MAILBOX_0_REG_OFFSET
;
145 count
= NUM_MAILBOX_REGS
;
146 for (i
= 0; i
< count
; i
++) {
147 if (ql_read_processor_data(qlge
, addr
, ®_status
)
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
;
156 rtn_val
= DDI_SUCCESS
;
159 ql_sem_unlock(qlge
, QL_PROCESSOR_SEM_MASK
);
166 * Write mail box command (upto 16) to MPI Firmware
169 ql_issue_mailbox_cmd(qlge_t
*qlge
, mbx_cmd_t
*mbx_cmd
)
171 int rtn_val
= DDI_FAILURE
;
175 * Get semaphore to access Processor Address and
176 * Processor Data Registers
178 if (ql_sem_spinlock(qlge
, QL_PROCESSOR_SEM_MASK
) != DDI_SUCCESS
) {
179 return (DDI_FAILURE
);
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
) {
187 if (qlge
->func_number
== qlge
->fn0_net
)
188 addr
= FUNC_0_IN_MAILBOX_0_REG_OFFSET
;
190 addr
= FUNC_1_IN_MAILBOX_0_REG_OFFSET
;
192 /* wait for mailbox registers to be ready to access */
193 if (ql_wait_processor_addr_reg_ready(qlge
) == DDI_FAILURE
)
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
));
206 * wait for mailbox cmd to be written before
207 * next write can start
209 if (ql_wait_processor_addr_reg_ready(qlge
) == DDI_FAILURE
)
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
;
216 ql_sem_unlock(qlge
, QL_PROCESSOR_SEM_MASK
);
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
228 ql_issue_mailbox_cmd_and_poll_rsp(qlge_t
*qlge
, mbx_cmd_t
*mbx_cmd
,
229 mbx_data_t
*p_results
)
231 int rtn_val
= DDI_FAILURE
;
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
);
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
)
251 QL_PRINT(DBG_MBX
, ("%s(%d) PI Intr received",
252 __func__
, qlge
->instance
));
253 (void) ql_read_mailbox_cmd(qlge
, p_results
, 0);
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
262 if (ql_async_event_parser(qlge
, p_results
) == B_FALSE
) {
264 * we get what we are waiting for,
265 * clear the interrupt
267 rtn_val
= DDI_SUCCESS
;
272 ("%s(%d) result ignored, not we wait for\n",
273 __func__
, qlge
->instance
));
275 ql_write_reg(qlge
, REG_HOST_CMD_STATUS
,
276 HOST_CMD_CLEAR_RISC_TO_HOST_INTR
);
277 } else { /* timeout */
280 rtn_val
= DDI_SUCCESS
;
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
293 ql_issue_mailbox_cmd_and_wait_rsp(qlge_t
*qlge
, mbx_cmd_t
*mbx_cmd
)
295 int rtn_val
= DDI_FAILURE
;
303 ASSERT(mutex_owned(&qlge
->mbx_mutex
));
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
];
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
);
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
) {
326 mbx_cmd
->timeout
* drv_usectohz(1000000);
328 timer
+= 5 * drv_usectohz(1000000);
330 if (cv_timedwait(&qlge
->cv_mbx_intr
, &qlge
->mbx_mutex
,
333 * The timeout time 'timer' was
334 * reached or expired without the condition
337 cmn_err(CE_WARN
, "%s(%d) Wait for Mailbox cmd "
339 __func__
, qlge
->instance
);
340 rtn_val
= DDI_FAILURE
;
344 ("%s(%d) mailbox completion signal received"
345 " \n", __func__
, qlge
->instance
));
346 for (i
= 0; i
< NUM_MAILBOX_REGS
; i
++) {
348 qlge
->received_mbx_cmds
.mb
[i
];
350 rtn_val
= DDI_SUCCESS
;
360 * Inteprete incoming asynchronous events
363 ql_async_event_parser(qlge_t
*qlge
, mbx_data_t
*mbx_cmds
)
365 uint32_t link_status
, cmd
;
368 boolean_t proc_done
= B_TRUE
;
369 mbx_cmd_t reply_cmd
= {0};
370 boolean_t fatal_error
= B_FALSE
;
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
));
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,"
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
);
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);
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
));
410 qlge
->link_type
= link_type
= (uint8_t)(link_status
& 0x07);
412 if (link_type
== XFI_NETWORK_INTERFACE
) {
415 ("%s(%d):Link type XFI_NETWORK_INTERFACE\n",
416 __func__
, qlge
->instance
));
417 } else if (link_type
== XAUI_NETWORK_INTERFACE
) {
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
) {
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
) {
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
) {
435 ("%s(%d):Link type EXT_10GBASE_T_PHY\n",
436 __func__
, qlge
->instance
));
437 } else if (link_type
== EXT_EXT_EDC_PHY
) {
440 ("%s(%d):Link type EXT_EXT_EDC_PHY\n",
441 __func__
, qlge
->instance
));
445 ("%s(%d):unknown Link type \n",
446 __func__
, qlge
->instance
));
448 cmn_err(CE_NOTE
, "qlge(%d) mpi link up! speed %dMbps\n",
449 qlge
->instance
, qlge
->speed
);
451 * start timer if not started to delay some time then
452 * check if link is really up or down
454 ql_restart_timer(qlge
);
457 case MBA_LINK_DOWN
/* 8012h */:
459 ("%s(%d): MBA_LINK_DOWN received\n",
460 __func__
, qlge
->instance
));
462 link_status
= mbx_cmds
->mb
[1];
464 QL_PRINT(DBG_MBX
, ("%s(%d): Link Status %x \n",
465 __func__
, qlge
->instance
, link_status
));
466 if (link_status
& 0x1) {
468 QL_PRINT(DBG_MBX
, ("%s(%d): Loss of signal \n",
469 __func__
, qlge
->instance
));
471 if (link_status
& 0x2) {
474 ("%s(%d): Auto-Negotiation Failed \n",
475 __func__
, qlge
->instance
));
477 if (link_status
& 0x4) {
480 ("%s(%d): XTI-Training Failed \n",
481 __func__
, qlge
->instance
));
484 cmn_err(CE_NOTE
, "qlge(%d) mpi link down!\n", qlge
->instance
);
485 ql_restart_timer(qlge
);
487 case MBA_IDC_COMPLETE
/* 8100h */:
490 ("%s(%d): MBA_IDC_COMPLETE received\n",
491 __func__
, qlge
->instance
));
492 cmd
= mbx_cmds
->mb
[1];
493 if (cmd
== MBC_STOP_FIRMWARE
) {
496 ("%s(%d): STOP_FIRMWARE event completed\n",
497 __func__
, qlge
->instance
));
498 } else if (cmd
== MBC_IDC_REQUEST
) {
501 ("%s(%d): IDC_REQUEST event completed\n",
502 __func__
, qlge
->instance
));
503 } else if (cmd
== MBC_PORT_RESET
) {
506 ("%s(%d): PORT_RESET event completed\n",
507 __func__
, qlge
->instance
));
508 } else if (cmd
== MBC_SET_PORT_CONFIG
) {
511 ("%s(%d): SET_PORT_CONFIG event "
512 "completed\n", __func__
, qlge
->instance
));
516 ("%s(%d): unknown IDC completion request"
517 " event %x %x\n", __func__
, qlge
->instance
,
518 mbx_cmds
->mb
[1], mbx_cmds
->mb
[2]));
523 case MBA_IDC_REQUEST_NOTIFICATION
/* 8101h */:
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
) {
531 ("%s(%d): STOP_FIRMWARE notification"
532 " received\n", __func__
, qlge
->instance
));
533 } else if (cmd
== MBC_IDC_REQUEST
) {
536 ("%s(%d): IDC_REQUEST notification "
537 "received\n", __func__
, qlge
->instance
));
538 } else if (cmd
== MBC_PORT_RESET
) {
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
) {
546 ("%s(%d): SET_PORT_CONFIG notification "
547 "received\n", __func__
, qlge
->instance
));
550 QL_PRINT(DBG_MBX
, ("%s(%d): "
551 "unknown request received %x %x\n",
552 __func__
, qlge
->instance
, mbx_cmds
->mb
[1],
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
)
563 "%s(%d) send IDC Ack failed.",
564 __func__
, qlge
->instance
);
567 * verify if the incoming outbound mailbox value is what
570 if (mbx_cmds
->mb
[0] == MBS_COMMAND_COMPLETE
) {
574 ("%s(%d): IDC Ack sent success.\n",
575 __func__
, qlge
->instance
));
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]));
584 case MBA_IDC_TIME_EXTENDED
/* 8102 */:
586 ("%s(%d): MBA_IDC_TIME_EXTENDED received\n",
587 __func__
, qlge
->instance
));
589 case MBA_DCBX_CONFIG_CHANGE
/* 8110 */:
591 ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n",
592 __func__
, qlge
->instance
));
594 case MBA_NOTIFICATION_LOST
/* 8120 */:
596 ("%s(%d): MBA_NOTIFICATION_LOST received\n",
597 __func__
, qlge
->instance
));
599 case MBA_SFT_TRANSCEIVER_INSERTION
/* 8130 */:
601 ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION "
602 "received\n", __func__
, qlge
->instance
));
604 case MBA_SFT_TRANSCEIVER_REMOVAL
/* 8140 */:
606 ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL "
607 "received\n", __func__
, qlge
->instance
));
609 case MBA_FIRMWARE_INIT_COMPLETE
/* 8400 */:
611 ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE "
612 "received\n", __func__
, qlge
->instance
));
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]));
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
;
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],
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
);
664 * MPI Interrupt handler
665 * Caller must have MBX_LOCK
668 ql_do_mpi_intr(qlge_t
*qlge
)
671 * we just need to read first few mailboxes that this adapter's MPI
672 * will write response to.
674 mutex_enter(&qlge
->mbx_mutex
);
676 (void) ql_read_mailbox_cmd(qlge
, &qlge
->received_mbx_cmds
,
680 * process PI interrupt as async events, if not done,
681 * then pass to mailbox processing
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
));
687 * If another thread is waiting for the mail box
688 * completion event to occur
690 if (qlge
->mbx_wait_completion
== 1) {
691 qlge
->mbx_wait_completion
= 0;
692 cv_broadcast(&qlge
->cv_mbx_intr
);
694 ("%s(%d) mailbox completion signaled \n",
695 __func__
, qlge
->instance
));
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 */
706 * Test if mailbox communication works
707 * This is used when Interrupt is not enabled
710 ql_mbx_test(qlge_t
*qlge
)
713 mbx_data_t mbx_results
;
715 int rtn_val
= DDI_FAILURE
;
717 for (i
= 0; i
< NUM_MAILBOX_REGS
; i
++)
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
);
727 /* delay for the processor interrupt is received */
728 if (ql_poll_processor_intr(qlge
, (uint8_t)mbx_cmds
.timeout
)
730 QL_PRINT(DBG_MBX
, ("%s(%d) PI Intr received",
731 __func__
, qlge
->instance
));
732 (void) ql_read_mailbox_cmd(qlge
, &mbx_results
, 0);
734 ql_write_reg(qlge
, REG_HOST_CMD_STATUS
,
735 HOST_CMD_CLEAR_RISC_TO_HOST_INTR
);
737 if (mbx_results
.mb
[0] != MBS_COMMAND_COMPLETE
/* 0x4000 */) {
740 for (i
= 1; i
< NUM_MAILBOX_REGS
; i
++) {
741 if (mbx_results
.mb
[i
] != i
) {
748 rtn_val
= DDI_SUCCESS
;
750 cmn_err(CE_WARN
, "%s(%d) mailbox test failed!",
751 __func__
, qlge
->instance
);
754 cmn_err(CE_WARN
, "%s(%d) mailbox testing error: "
755 "PI Intr not received ", __func__
, qlge
->instance
);
763 * Test if mailbox communication works
764 * This is used when Interrupt is enabled
768 ql_mbx_test2(qlge_t
*qlge
)
770 mbx_cmd_t mbx_cmds
= {0};
772 int rtn_val
= DDI_FAILURE
;
774 for (i
= 0; i
< NUM_MAILBOX_REGS
; i
++)
777 mbx_cmds
.mb
[0] = MBC_MAILBOX_REGISTER_TEST
; /* 0x06 */
778 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge
, &mbx_cmds
) != DDI_SUCCESS
) {
780 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
781 __func__
, qlge
->instance
);
785 /* verify if the incoming outbound mailbox value is what we just sent */
786 if (mbx_cmds
.mb
[0] != MBS_COMMAND_COMPLETE
/* 0x4000 */) {
789 for (i
= 1; i
< qlge
->max_read_mbx
; i
++) {
790 if (mbx_cmds
.mb
[i
] != i
) {
797 rtn_val
= DDI_SUCCESS
;
799 cmn_err(CE_WARN
, "%s(%d) mailbox test failed!",
800 __func__
, qlge
->instance
);
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
);
816 ql_get_fw_state(qlge_t
*qlge
, uint32_t *fw_state_ptr
)
818 int rtn_val
= DDI_FAILURE
;
819 mbx_cmd_t mbx_cmds
= {0};
821 mbx_cmds
.mb
[0] = MBC_GET_FIRMWARE_STATE
;
823 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge
, &mbx_cmds
)
825 cmn_err(CE_WARN
, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
826 " failed.", __func__
, qlge
->instance
);
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]);
835 QL_PRINT(DBG_MBX
, ("firmware state: 0x%x\n", mbx_cmds
.mb
[1]));
837 if (fw_state_ptr
!= NULL
)
838 *fw_state_ptr
= mbx_cmds
.mb
[1];
839 rtn_val
= DDI_SUCCESS
;
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
);
850 * Send a IDC Request to firmware to notify all functions
851 * or any specific functions on the same port
855 ql_set_IDC_Req(qlge_t
*qlge
, uint8_t dest_functions
, uint8_t timeout
)
857 int rtn_val
= DDI_FAILURE
;
858 mbx_cmd_t mbx_cmds
= {0};
860 mbx_cmds
.mb
[0] = MBC_IDC_REQUEST
/* 0x100 */;
861 mbx_cmds
.mb
[1] = (timeout
<<8) | qlge
->func_number
;
863 switch (dest_functions
) {
864 case IDC_REQ_DEST_FUNC_ALL
:
865 mbx_cmds
.mb
[1] |= IDC_REQ_ALL_DEST_FUNC_MASK
;
868 case IDC_REQ_DEST_FUNC_0
:
869 mbx_cmds
.mb
[2] = IDC_REQ_DEST_FUNC_0_MASK
;
871 case IDC_REQ_DEST_FUNC_1
:
872 mbx_cmds
.mb
[2] = IDC_REQ_DEST_FUNC_1_MASK
;
874 case IDC_REQ_DEST_FUNC_2
:
875 mbx_cmds
.mb
[2] = IDC_REQ_DEST_FUNC_2_MASK
;
877 case IDC_REQ_DEST_FUNC_3
:
878 mbx_cmds
.mb
[2] = IDC_REQ_DEST_FUNC_3_MASK
;
881 cmn_err(CE_WARN
, "Wrong dest functions %x",
885 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge
, &mbx_cmds
) != DDI_SUCCESS
) {
887 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
888 __func__
, qlge
->instance
);
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
);
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]);
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
);
921 * ql_set_mpi_port_config
922 * Send new port configuration.to mpi
926 ql_set_mpi_port_config(qlge_t
*qlge
, port_cfg_info_t new_cfg
)
928 int rtn_val
= DDI_FAILURE
;
929 mbx_cmd_t mbx_cmds
= {0};
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
;
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
);
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]);
946 rtn_val
= DDI_SUCCESS
;
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
);
956 ql_set_pause_mode(qlge_t
*qlge
)
958 uint32_t pause_bit_mask
= 0x60; /* bit 5-6 */
960 /* clear pause bits */
961 qlge
->port_cfg_info
.link_cfg
&= ~pause_bit_mask
;
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
;
969 return (ql_set_mpi_port_config(qlge
, qlge
->port_cfg_info
));
973 ql_set_loop_back_mode(qlge_t
*qlge
)
975 uint32_t loop_back_bit_mask
= 0x0e; /* bit 1-3 */
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
;
987 return (ql_set_mpi_port_config(qlge
, qlge
->port_cfg_info
));
992 * Get port configuration.
996 ql_get_port_cfg(qlge_t
*qlge
)
998 int rtn_val
= DDI_FAILURE
;
999 mbx_cmd_t mbx_cmds
= {0};
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
);
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
;
1020 cmn_err(CE_WARN
, "bad link_cfg: 0x%x, max_frame_size:"
1021 " %d bytes", mbx_cmds
.mb
[1], mbx_cmds
.mb
[2]);
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
);
1033 * qlge_get_link_status
1035 * mailbox cmd:0x124h
1038 qlge_get_link_status(qlge_t
*qlge
,
1039 struct qlnic_link_status_info
*link_status_ptr
)
1041 int rtn_val
= DDI_FAILURE
;
1042 mbx_cmd_t mbx_cmds
= {0};
1044 mbx_cmds
.mb
[0] = MBC_GET_LINK_STATUS
/* 0x124 */;
1046 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge
, &mbx_cmds
)
1049 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1050 __func__
, qlge
->instance
);
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]);
1060 ("link status: status1 : 0x%x, status2 : 0x%x, "
1062 mbx_cmds
.mb
[1], mbx_cmds
.mb
[2], mbx_cmds
.mb
[3]));
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];
1071 rtn_val
= DDI_SUCCESS
;
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
);
1081 * ql_get_firmware_version
1082 * Get firmware version.
1085 ql_get_firmware_version(qlge_t
*qlge
,
1086 struct qlnic_mpi_version_info
*mpi_version_ptr
)
1088 int rtn_val
= DDI_FAILURE
;
1089 mbx_cmd_t mbx_cmds
= {0};
1091 mbx_cmds
.mb
[0] = MBC_ABOUT_FIRMWARE
/* 0x08 */;
1093 if (ql_issue_mailbox_cmd_and_wait_rsp(qlge
, &mbx_cmds
)
1096 "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
1097 __func__
, qlge
->instance
);
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]);
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
);
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
);
1135 rtn_val
= DDI_SUCCESS
;
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
);
1145 * Trigger a system error event
1148 ql_trigger_system_error_event(qlge_t
*qlge
)
1150 mbx_cmd_t mbx_cmds
= {0};
1151 int rtn_val
= DDI_FAILURE
;
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
);
1159 rtn_val
= DDI_SUCCESS
;
1165 * Reset the MPI RISC Processor
1168 ql_reset_mpi_risc(qlge_t
*qlge
)
1170 int rtn_val
= DDI_FAILURE
;
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
);
1179 ql_write_reg(qlge
, REG_HOST_CMD_STATUS
, HOST_CMD_CLEAR_RISC_RESET
);
1180 rtn_val
= DDI_SUCCESS
;
1186 ql_read_risc_ram(qlge_t
*qlge
, uint32_t risc_address
, uint64_t bp
,
1187 uint32_t word_count
)
1189 int rval
= DDI_FAILURE
;
1191 mbx_cmd_t
*mcp
= &mc
;
1192 mbx_data_t mbx_results
;
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
);
1208 mcp
->timeout
= 10 /* MAILBOX_TOV */;
1210 if (ql_issue_mailbox_cmd_and_poll_rsp(qlge
, mcp
, &mbx_results
)
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
));
1221 cmn_err(CE_WARN
, "read_risc_ram(%d): failed, status %x",
1222 qlge
->instance
, mbx_results
.mb
[0]);