110997SSukumar.Swaminathan@Sun.COM /*
210997SSukumar.Swaminathan@Sun.COM * CDDL HEADER START
310997SSukumar.Swaminathan@Sun.COM *
410997SSukumar.Swaminathan@Sun.COM * The contents of this file are subject to the terms of the
510997SSukumar.Swaminathan@Sun.COM * Common Development and Distribution License (the "License").
610997SSukumar.Swaminathan@Sun.COM * You may not use this file except in compliance with the License.
710997SSukumar.Swaminathan@Sun.COM *
810997SSukumar.Swaminathan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910997SSukumar.Swaminathan@Sun.COM * or http://www.opensolaris.org/os/licensing.
1010997SSukumar.Swaminathan@Sun.COM * See the License for the specific language governing permissions
1110997SSukumar.Swaminathan@Sun.COM * and limitations under the License.
1210997SSukumar.Swaminathan@Sun.COM *
1310997SSukumar.Swaminathan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1410997SSukumar.Swaminathan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510997SSukumar.Swaminathan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1610997SSukumar.Swaminathan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1710997SSukumar.Swaminathan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1810997SSukumar.Swaminathan@Sun.COM *
1910997SSukumar.Swaminathan@Sun.COM * CDDL HEADER END
2010997SSukumar.Swaminathan@Sun.COM */
2110997SSukumar.Swaminathan@Sun.COM
2210997SSukumar.Swaminathan@Sun.COM /*
2312073SSukumar.Swaminathan@Sun.COM * Copyright 2010 QLogic Corporation. All rights reserved.
2410997SSukumar.Swaminathan@Sun.COM */
2510997SSukumar.Swaminathan@Sun.COM
2610997SSukumar.Swaminathan@Sun.COM #include <qlge.h>
2710997SSukumar.Swaminathan@Sun.COM
2810997SSukumar.Swaminathan@Sun.COM static int ql_async_event_parser(qlge_t *, mbx_data_t *);
2910997SSukumar.Swaminathan@Sun.COM
3010997SSukumar.Swaminathan@Sun.COM /*
3110997SSukumar.Swaminathan@Sun.COM * Wait upto timeout seconds for Processor Interrupt
3210997SSukumar.Swaminathan@Sun.COM * if timeout is 0, then wait for default waittime
3310997SSukumar.Swaminathan@Sun.COM */
3410997SSukumar.Swaminathan@Sun.COM static int
ql_poll_processor_intr(qlge_t * qlge,uint8_t timeout)3510997SSukumar.Swaminathan@Sun.COM ql_poll_processor_intr(qlge_t *qlge, uint8_t timeout)
3610997SSukumar.Swaminathan@Sun.COM {
3710997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_SUCCESS;
3810997SSukumar.Swaminathan@Sun.COM
3910997SSukumar.Swaminathan@Sun.COM if (ql_wait_reg_bit(qlge, REG_STATUS, STS_PI, BIT_SET, timeout)
4010997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
4110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "Polling for processor interrupt failed.");
4210997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_FAILURE;
4310997SSukumar.Swaminathan@Sun.COM }
4410997SSukumar.Swaminathan@Sun.COM return (rtn_val);
4510997SSukumar.Swaminathan@Sun.COM }
4610997SSukumar.Swaminathan@Sun.COM
4710997SSukumar.Swaminathan@Sun.COM /*
4810997SSukumar.Swaminathan@Sun.COM * Wait for mailbox Processor Register Ready
4910997SSukumar.Swaminathan@Sun.COM */
5010997SSukumar.Swaminathan@Sun.COM static int
ql_wait_processor_addr_reg_ready(qlge_t * qlge)5110997SSukumar.Swaminathan@Sun.COM ql_wait_processor_addr_reg_ready(qlge_t *qlge)
5210997SSukumar.Swaminathan@Sun.COM {
5310997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_SUCCESS;
5410997SSukumar.Swaminathan@Sun.COM
5510997SSukumar.Swaminathan@Sun.COM if (ql_wait_reg_bit(qlge, REG_PROCESSOR_ADDR,
5610997SSukumar.Swaminathan@Sun.COM PROCESSOR_ADDRESS_RDY, BIT_SET, 0) != DDI_SUCCESS) {
5710997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
5810997SSukumar.Swaminathan@Sun.COM "Wait for processor address register ready timeout.");
5910997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_FAILURE;
6010997SSukumar.Swaminathan@Sun.COM }
6110997SSukumar.Swaminathan@Sun.COM return (rtn_val);
6210997SSukumar.Swaminathan@Sun.COM }
6310997SSukumar.Swaminathan@Sun.COM
6410997SSukumar.Swaminathan@Sun.COM /*
6510997SSukumar.Swaminathan@Sun.COM * Read and write MPI registers using the indirect register interface
6610997SSukumar.Swaminathan@Sun.COM * Assume all the locks&semaphore have been acquired
6710997SSukumar.Swaminathan@Sun.COM */
6810997SSukumar.Swaminathan@Sun.COM int
ql_write_processor_data(qlge_t * qlge,uint32_t addr,uint32_t data)6910997SSukumar.Swaminathan@Sun.COM ql_write_processor_data(qlge_t *qlge, uint32_t addr, uint32_t data)
7010997SSukumar.Swaminathan@Sun.COM {
7110997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
7210997SSukumar.Swaminathan@Sun.COM
7310997SSukumar.Swaminathan@Sun.COM /* wait for processor address register ready */
7410997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
7510997SSukumar.Swaminathan@Sun.COM goto out;
7610997SSukumar.Swaminathan@Sun.COM /* write the data to the data reg */
7710997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_PROCESSOR_DATA, data);
7810997SSukumar.Swaminathan@Sun.COM /* trigger the write */
7910997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
8010997SSukumar.Swaminathan@Sun.COM /* wait for register to come ready */
8110997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
8210997SSukumar.Swaminathan@Sun.COM goto out;
8310997SSukumar.Swaminathan@Sun.COM
8410997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
8510997SSukumar.Swaminathan@Sun.COM
8610997SSukumar.Swaminathan@Sun.COM out:
8710997SSukumar.Swaminathan@Sun.COM return (rtn_val);
8810997SSukumar.Swaminathan@Sun.COM
8910997SSukumar.Swaminathan@Sun.COM }
9010997SSukumar.Swaminathan@Sun.COM
9110997SSukumar.Swaminathan@Sun.COM /*
9210997SSukumar.Swaminathan@Sun.COM * Read from processor register
9310997SSukumar.Swaminathan@Sun.COM */
9410997SSukumar.Swaminathan@Sun.COM int
ql_read_processor_data(qlge_t * qlge,uint32_t addr,uint32_t * data)9510997SSukumar.Swaminathan@Sun.COM ql_read_processor_data(qlge_t *qlge, uint32_t addr, uint32_t *data)
9610997SSukumar.Swaminathan@Sun.COM {
9710997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
9810997SSukumar.Swaminathan@Sun.COM
9910997SSukumar.Swaminathan@Sun.COM /* enable read operation */
10010997SSukumar.Swaminathan@Sun.COM addr |= PROCESSOR_ADDRESS_READ;
10110997SSukumar.Swaminathan@Sun.COM /* wait for processor address register ready */
10210997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
10310997SSukumar.Swaminathan@Sun.COM goto out;
10410997SSukumar.Swaminathan@Sun.COM
10510997SSukumar.Swaminathan@Sun.COM /* Write read address, wait for data ready in Data register */
10610997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
10710997SSukumar.Swaminathan@Sun.COM /* wait for data ready */
10810997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
10910997SSukumar.Swaminathan@Sun.COM goto out;
11010997SSukumar.Swaminathan@Sun.COM /* read data */
11110997SSukumar.Swaminathan@Sun.COM *data = ql_read_reg(qlge, REG_PROCESSOR_DATA);
11210997SSukumar.Swaminathan@Sun.COM
11310997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
11410997SSukumar.Swaminathan@Sun.COM
11510997SSukumar.Swaminathan@Sun.COM out:
11610997SSukumar.Swaminathan@Sun.COM return (rtn_val);
11710997SSukumar.Swaminathan@Sun.COM
11810997SSukumar.Swaminathan@Sun.COM }
11910997SSukumar.Swaminathan@Sun.COM
12010997SSukumar.Swaminathan@Sun.COM /*
12110997SSukumar.Swaminathan@Sun.COM * Read "count" number of outgoing Mailbox register starting
12210997SSukumar.Swaminathan@Sun.COM * from mailbox #0 if count is 0 then read all mailboxes
12310997SSukumar.Swaminathan@Sun.COM */
12410997SSukumar.Swaminathan@Sun.COM static int
ql_read_mailbox_cmd(qlge_t * qlge,mbx_data_t * mbx_buf,uint32_t count)12510997SSukumar.Swaminathan@Sun.COM ql_read_mailbox_cmd(qlge_t *qlge, mbx_data_t *mbx_buf, uint32_t count)
12610997SSukumar.Swaminathan@Sun.COM {
12710997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
12810997SSukumar.Swaminathan@Sun.COM uint32_t reg_status;
12910997SSukumar.Swaminathan@Sun.COM uint32_t addr;
13010997SSukumar.Swaminathan@Sun.COM int i;
13110997SSukumar.Swaminathan@Sun.COM
13210997SSukumar.Swaminathan@Sun.COM if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
13310997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
13410997SSukumar.Swaminathan@Sun.COM "%s(%d) get QL_PROCESSOR_SEM_MASK time out error",
13510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
13610997SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
13710997SSukumar.Swaminathan@Sun.COM }
13810997SSukumar.Swaminathan@Sun.COM
13910997SSukumar.Swaminathan@Sun.COM if (qlge->func_number == qlge->fn0_net)
14010997SSukumar.Swaminathan@Sun.COM addr = FUNC_0_OUT_MAILBOX_0_REG_OFFSET;
14110997SSukumar.Swaminathan@Sun.COM else
14210997SSukumar.Swaminathan@Sun.COM addr = FUNC_1_OUT_MAILBOX_0_REG_OFFSET;
14310997SSukumar.Swaminathan@Sun.COM
14410997SSukumar.Swaminathan@Sun.COM if (count == 0)
14510997SSukumar.Swaminathan@Sun.COM count = NUM_MAILBOX_REGS;
14610997SSukumar.Swaminathan@Sun.COM for (i = 0; i < count; i++) {
14710997SSukumar.Swaminathan@Sun.COM if (ql_read_processor_data(qlge, addr, ®_status)
14810997SSukumar.Swaminathan@Sun.COM == DDI_FAILURE)
14910997SSukumar.Swaminathan@Sun.COM goto out;
15010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) mailbox %d value 0x%x\n",
15110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, i, reg_status));
15210997SSukumar.Swaminathan@Sun.COM mbx_buf->mb[i] = reg_status;
15310997SSukumar.Swaminathan@Sun.COM addr ++;
15410997SSukumar.Swaminathan@Sun.COM }
15510997SSukumar.Swaminathan@Sun.COM
15610997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
15710997SSukumar.Swaminathan@Sun.COM
15810997SSukumar.Swaminathan@Sun.COM out:
15910997SSukumar.Swaminathan@Sun.COM ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
16010997SSukumar.Swaminathan@Sun.COM
16110997SSukumar.Swaminathan@Sun.COM return (rtn_val);
16210997SSukumar.Swaminathan@Sun.COM
16310997SSukumar.Swaminathan@Sun.COM }
16410997SSukumar.Swaminathan@Sun.COM
16510997SSukumar.Swaminathan@Sun.COM /*
16610997SSukumar.Swaminathan@Sun.COM * Write mail box command (upto 16) to MPI Firmware
16710997SSukumar.Swaminathan@Sun.COM */
16810997SSukumar.Swaminathan@Sun.COM int
ql_issue_mailbox_cmd(qlge_t * qlge,mbx_cmd_t * mbx_cmd)16910997SSukumar.Swaminathan@Sun.COM ql_issue_mailbox_cmd(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
17010997SSukumar.Swaminathan@Sun.COM {
17110997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
17210997SSukumar.Swaminathan@Sun.COM uint32_t addr;
17310997SSukumar.Swaminathan@Sun.COM int i;
17410997SSukumar.Swaminathan@Sun.COM /*
17510997SSukumar.Swaminathan@Sun.COM * Get semaphore to access Processor Address and
17610997SSukumar.Swaminathan@Sun.COM * Processor Data Registers
17710997SSukumar.Swaminathan@Sun.COM */
17810997SSukumar.Swaminathan@Sun.COM if (ql_sem_spinlock(qlge, QL_PROCESSOR_SEM_MASK) != DDI_SUCCESS) {
17910997SSukumar.Swaminathan@Sun.COM return (DDI_FAILURE);
18010997SSukumar.Swaminathan@Sun.COM }
18110997SSukumar.Swaminathan@Sun.COM /* ensure no overwriting current command */
18210997SSukumar.Swaminathan@Sun.COM if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS,
18310997SSukumar.Swaminathan@Sun.COM HOST_TO_MPI_INTR_NOT_DONE, BIT_RESET, 0) != DDI_SUCCESS) {
18410997SSukumar.Swaminathan@Sun.COM goto out;
18510997SSukumar.Swaminathan@Sun.COM }
18610997SSukumar.Swaminathan@Sun.COM
18710997SSukumar.Swaminathan@Sun.COM if (qlge->func_number == qlge->fn0_net)
18810997SSukumar.Swaminathan@Sun.COM addr = FUNC_0_IN_MAILBOX_0_REG_OFFSET;
18910997SSukumar.Swaminathan@Sun.COM else
19010997SSukumar.Swaminathan@Sun.COM addr = FUNC_1_IN_MAILBOX_0_REG_OFFSET;
19110997SSukumar.Swaminathan@Sun.COM
19210997SSukumar.Swaminathan@Sun.COM /* wait for mailbox registers to be ready to access */
19310997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
19410997SSukumar.Swaminathan@Sun.COM goto out;
19510997SSukumar.Swaminathan@Sun.COM
19610997SSukumar.Swaminathan@Sun.COM /* issue mailbox command one by one */
19710997SSukumar.Swaminathan@Sun.COM for (i = 0; i < NUM_MAILBOX_REGS; i++) {
19810997SSukumar.Swaminathan@Sun.COM /* write sending cmd to mailbox data register */
19910997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_PROCESSOR_DATA, mbx_cmd->mb[i]);
20010997SSukumar.Swaminathan@Sun.COM /* write mailbox address to address register */
20110997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_PROCESSOR_ADDR, addr);
20210997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) write %x to mailbox(%x) addr %x \n",
20310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmd->mb[i], i, addr));
20410997SSukumar.Swaminathan@Sun.COM addr++;
20510997SSukumar.Swaminathan@Sun.COM /*
20610997SSukumar.Swaminathan@Sun.COM * wait for mailbox cmd to be written before
20710997SSukumar.Swaminathan@Sun.COM * next write can start
20810997SSukumar.Swaminathan@Sun.COM */
20910997SSukumar.Swaminathan@Sun.COM if (ql_wait_processor_addr_reg_ready(qlge) == DDI_FAILURE)
21010997SSukumar.Swaminathan@Sun.COM goto out;
21110997SSukumar.Swaminathan@Sun.COM }
21210997SSukumar.Swaminathan@Sun.COM /* inform MPI that new mailbox commands are available */
21310997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_INTR);
21410997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
21510997SSukumar.Swaminathan@Sun.COM out:
21610997SSukumar.Swaminathan@Sun.COM ql_sem_unlock(qlge, QL_PROCESSOR_SEM_MASK);
21710997SSukumar.Swaminathan@Sun.COM return (rtn_val);
21810997SSukumar.Swaminathan@Sun.COM }
21910997SSukumar.Swaminathan@Sun.COM
22010997SSukumar.Swaminathan@Sun.COM /*
22110997SSukumar.Swaminathan@Sun.COM * Send mail box command (upto 16) to MPI Firmware
22210997SSukumar.Swaminathan@Sun.COM * and polling for MPI mailbox completion response when
22310997SSukumar.Swaminathan@Sun.COM * interrupt is not enabled.
22410997SSukumar.Swaminathan@Sun.COM * The MBX_LOCK mutexe should have been held and released
22510997SSukumar.Swaminathan@Sun.COM * externally
22610997SSukumar.Swaminathan@Sun.COM */
22710997SSukumar.Swaminathan@Sun.COM int
ql_issue_mailbox_cmd_and_poll_rsp(qlge_t * qlge,mbx_cmd_t * mbx_cmd,mbx_data_t * p_results)22810997SSukumar.Swaminathan@Sun.COM ql_issue_mailbox_cmd_and_poll_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd,
22910997SSukumar.Swaminathan@Sun.COM mbx_data_t *p_results)
23010997SSukumar.Swaminathan@Sun.COM {
23110997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
23210997SSukumar.Swaminathan@Sun.COM boolean_t done;
23310997SSukumar.Swaminathan@Sun.COM int max_wait;
23410997SSukumar.Swaminathan@Sun.COM
23510997SSukumar.Swaminathan@Sun.COM if (mbx_cmd == NULL)
23610997SSukumar.Swaminathan@Sun.COM goto err;
23710997SSukumar.Swaminathan@Sun.COM
23810997SSukumar.Swaminathan@Sun.COM rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
23910997SSukumar.Swaminathan@Sun.COM if (rtn_val != DDI_SUCCESS) {
24010997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
24110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
24210997SSukumar.Swaminathan@Sun.COM goto err;
24310997SSukumar.Swaminathan@Sun.COM }
24410997SSukumar.Swaminathan@Sun.COM done = B_FALSE;
24510997SSukumar.Swaminathan@Sun.COM max_wait = 5; /* wait upto 5 PI interrupt */
24610997SSukumar.Swaminathan@Sun.COM /* delay for the processor interrupt is received */
24710997SSukumar.Swaminathan@Sun.COM while ((done != B_TRUE) && (max_wait--)) {
24810997SSukumar.Swaminathan@Sun.COM /* wait up to 5s for PI interrupt */
24910997SSukumar.Swaminathan@Sun.COM if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmd->timeout)
25010997SSukumar.Swaminathan@Sun.COM == DDI_SUCCESS) {
25110997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
25210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
25311016SSukumar.Swaminathan@Sun.COM (void) ql_read_mailbox_cmd(qlge, p_results, 0);
25410997SSukumar.Swaminathan@Sun.COM /*
25510997SSukumar.Swaminathan@Sun.COM * Sometimes, the incoming messages is not what we are
25610997SSukumar.Swaminathan@Sun.COM * waiting for, ie. async events, then, continue to
25710997SSukumar.Swaminathan@Sun.COM * wait. If it is the result * of previous mailbox
25810997SSukumar.Swaminathan@Sun.COM * command, then Done. No matter what, send
25910997SSukumar.Swaminathan@Sun.COM * HOST_CMD_CLEAR_RISC_TO_HOST_INTR to clear each
26010997SSukumar.Swaminathan@Sun.COM * PI interrupt
26110997SSukumar.Swaminathan@Sun.COM */
26210997SSukumar.Swaminathan@Sun.COM if (ql_async_event_parser(qlge, p_results) == B_FALSE) {
26310997SSukumar.Swaminathan@Sun.COM /*
26410997SSukumar.Swaminathan@Sun.COM * we get what we are waiting for,
26510997SSukumar.Swaminathan@Sun.COM * clear the interrupt
26610997SSukumar.Swaminathan@Sun.COM */
26710997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
26810997SSukumar.Swaminathan@Sun.COM done = B_TRUE;
26910997SSukumar.Swaminathan@Sun.COM } else {
27010997SSukumar.Swaminathan@Sun.COM /*EMPTY*/
27110997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
27210997SSukumar.Swaminathan@Sun.COM ("%s(%d) result ignored, not we wait for\n",
27310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
27410997SSukumar.Swaminathan@Sun.COM }
27510997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS,
27610997SSukumar.Swaminathan@Sun.COM HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
27710997SSukumar.Swaminathan@Sun.COM } else { /* timeout */
27810997SSukumar.Swaminathan@Sun.COM done = B_TRUE;
27910997SSukumar.Swaminathan@Sun.COM }
28010997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
28110997SSukumar.Swaminathan@Sun.COM }
28210997SSukumar.Swaminathan@Sun.COM err:
28310997SSukumar.Swaminathan@Sun.COM return (rtn_val);
28410997SSukumar.Swaminathan@Sun.COM }
28510997SSukumar.Swaminathan@Sun.COM /*
28610997SSukumar.Swaminathan@Sun.COM * Send mail box command (upto 16) to MPI Firmware
28710997SSukumar.Swaminathan@Sun.COM * and wait for MPI mailbox completion response which
28810997SSukumar.Swaminathan@Sun.COM * is saved in interrupt. Thus, this function can only
28910997SSukumar.Swaminathan@Sun.COM * be used after interrupt is enabled.
29010997SSukumar.Swaminathan@Sun.COM * Must hold MBX mutex before calling this function
29110997SSukumar.Swaminathan@Sun.COM */
29210997SSukumar.Swaminathan@Sun.COM static int
ql_issue_mailbox_cmd_and_wait_rsp(qlge_t * qlge,mbx_cmd_t * mbx_cmd)29310997SSukumar.Swaminathan@Sun.COM ql_issue_mailbox_cmd_and_wait_rsp(qlge_t *qlge, mbx_cmd_t *mbx_cmd)
29410997SSukumar.Swaminathan@Sun.COM {
29510997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
29610997SSukumar.Swaminathan@Sun.COM clock_t timer;
29710997SSukumar.Swaminathan@Sun.COM int i;
29810997SSukumar.Swaminathan@Sun.COM int done = 0;
29910997SSukumar.Swaminathan@Sun.COM
30010997SSukumar.Swaminathan@Sun.COM if (mbx_cmd == NULL)
30110997SSukumar.Swaminathan@Sun.COM goto err;
30210997SSukumar.Swaminathan@Sun.COM
30310997SSukumar.Swaminathan@Sun.COM ASSERT(mutex_owned(&qlge->mbx_mutex));
30410997SSukumar.Swaminathan@Sun.COM
30510997SSukumar.Swaminathan@Sun.COM /* if interrupts are not enabled, poll when results are available */
30610997SSukumar.Swaminathan@Sun.COM if (!(qlge->flags & INTERRUPTS_ENABLED)) {
30710997SSukumar.Swaminathan@Sun.COM rtn_val = ql_issue_mailbox_cmd_and_poll_rsp(qlge, mbx_cmd,
30810997SSukumar.Swaminathan@Sun.COM &qlge->received_mbx_cmds);
30910997SSukumar.Swaminathan@Sun.COM if (rtn_val == DDI_SUCCESS) {
31010997SSukumar.Swaminathan@Sun.COM for (i = 0; i < NUM_MAILBOX_REGS; i++)
31110997SSukumar.Swaminathan@Sun.COM mbx_cmd->mb[i] = qlge->received_mbx_cmds.mb[i];
31210997SSukumar.Swaminathan@Sun.COM }
31310997SSukumar.Swaminathan@Sun.COM } else {
31410997SSukumar.Swaminathan@Sun.COM rtn_val = ql_issue_mailbox_cmd(qlge, mbx_cmd);
31510997SSukumar.Swaminathan@Sun.COM if (rtn_val != DDI_SUCCESS) {
31610997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd failed",
31710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
31810997SSukumar.Swaminathan@Sun.COM goto err;
31910997SSukumar.Swaminathan@Sun.COM }
32010997SSukumar.Swaminathan@Sun.COM qlge->mbx_wait_completion = 1;
32110997SSukumar.Swaminathan@Sun.COM while (!done && qlge->mbx_wait_completion && !ddi_in_panic()) {
32210997SSukumar.Swaminathan@Sun.COM /* default 5 seconds from now to timeout */
32310997SSukumar.Swaminathan@Sun.COM timer = ddi_get_lbolt();
32410997SSukumar.Swaminathan@Sun.COM if (mbx_cmd->timeout) {
32510997SSukumar.Swaminathan@Sun.COM timer +=
32610997SSukumar.Swaminathan@Sun.COM mbx_cmd->timeout * drv_usectohz(1000000);
32710997SSukumar.Swaminathan@Sun.COM } else {
32810997SSukumar.Swaminathan@Sun.COM timer += 5 * drv_usectohz(1000000);
32910997SSukumar.Swaminathan@Sun.COM }
33010997SSukumar.Swaminathan@Sun.COM if (cv_timedwait(&qlge->cv_mbx_intr, &qlge->mbx_mutex,
33110997SSukumar.Swaminathan@Sun.COM timer) == -1) {
33210997SSukumar.Swaminathan@Sun.COM /*
33310997SSukumar.Swaminathan@Sun.COM * The timeout time 'timer' was
33410997SSukumar.Swaminathan@Sun.COM * reached or expired without the condition
33510997SSukumar.Swaminathan@Sun.COM * being signaled.
33610997SSukumar.Swaminathan@Sun.COM */
33710997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) Wait for Mailbox cmd "
33810997SSukumar.Swaminathan@Sun.COM "complete timeout.",
33910997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
34010997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_FAILURE;
34110997SSukumar.Swaminathan@Sun.COM done = 1;
34210997SSukumar.Swaminathan@Sun.COM } else {
34310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
34410997SSukumar.Swaminathan@Sun.COM ("%s(%d) mailbox completion signal received"
34510997SSukumar.Swaminathan@Sun.COM " \n", __func__, qlge->instance));
34610997SSukumar.Swaminathan@Sun.COM for (i = 0; i < NUM_MAILBOX_REGS; i++) {
34710997SSukumar.Swaminathan@Sun.COM mbx_cmd->mb[i] =
34810997SSukumar.Swaminathan@Sun.COM qlge->received_mbx_cmds.mb[i];
34910997SSukumar.Swaminathan@Sun.COM }
35010997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
35110997SSukumar.Swaminathan@Sun.COM done = 1;
35210997SSukumar.Swaminathan@Sun.COM }
35310997SSukumar.Swaminathan@Sun.COM }
35410997SSukumar.Swaminathan@Sun.COM }
35510997SSukumar.Swaminathan@Sun.COM err:
35610997SSukumar.Swaminathan@Sun.COM return (rtn_val);
35710997SSukumar.Swaminathan@Sun.COM }
35810997SSukumar.Swaminathan@Sun.COM
35910997SSukumar.Swaminathan@Sun.COM /*
36010997SSukumar.Swaminathan@Sun.COM * Inteprete incoming asynchronous events
36110997SSukumar.Swaminathan@Sun.COM */
36210997SSukumar.Swaminathan@Sun.COM static int
ql_async_event_parser(qlge_t * qlge,mbx_data_t * mbx_cmds)36310997SSukumar.Swaminathan@Sun.COM ql_async_event_parser(qlge_t *qlge, mbx_data_t *mbx_cmds)
36410997SSukumar.Swaminathan@Sun.COM {
36510997SSukumar.Swaminathan@Sun.COM uint32_t link_status, cmd;
36610997SSukumar.Swaminathan@Sun.COM uint8_t link_speed;
36710997SSukumar.Swaminathan@Sun.COM uint8_t link_type;
36810997SSukumar.Swaminathan@Sun.COM boolean_t proc_done = B_TRUE;
36910997SSukumar.Swaminathan@Sun.COM mbx_cmd_t reply_cmd = {0};
37012073SSukumar.Swaminathan@Sun.COM boolean_t fatal_error = B_FALSE;
37110997SSukumar.Swaminathan@Sun.COM
37210997SSukumar.Swaminathan@Sun.COM switch (mbx_cmds->mb[0]) {
37310997SSukumar.Swaminathan@Sun.COM case MBA_IDC_INTERMEDIATE_COMPLETE /* 1000h */:
37410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):"
37510997SSukumar.Swaminathan@Sun.COM "MBA_IDC_INTERMEDIATE_COMPLETE received\n",
37610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
37710997SSukumar.Swaminathan@Sun.COM break;
37810997SSukumar.Swaminathan@Sun.COM case MBA_SYSTEM_ERR /* 8002h */:
37910997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d): MBA_SYSTEM_ERR received",
38010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
38110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d): File id %x, Line # %x,"
38210997SSukumar.Swaminathan@Sun.COM "Firmware Ver# %x",
38310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmds->mb[1],
38410997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[2], mbx_cmds->mb[3]);
38512073SSukumar.Swaminathan@Sun.COM fatal_error = B_TRUE;
38611016SSukumar.Swaminathan@Sun.COM (void) ql_8xxx_binary_core_dump(qlge, &qlge->ql_mpi_coredump);
38710997SSukumar.Swaminathan@Sun.COM break;
38810997SSukumar.Swaminathan@Sun.COM case MBA_LINK_UP /* 8011h */:
38910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): MBA_LINK_UP received\n",
39010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
39110997SSukumar.Swaminathan@Sun.COM link_status = mbx_cmds->mb[1];
39210997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
39310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, link_status));
39410997SSukumar.Swaminathan@Sun.COM link_speed = (uint8_t)((link_status >> 3) & 0x07);
39510997SSukumar.Swaminathan@Sun.COM
39610997SSukumar.Swaminathan@Sun.COM if (link_speed == 0) {
39710997SSukumar.Swaminathan@Sun.COM qlge->speed = SPEED_100;
39810997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link speed 100M\n",
39910997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
40010997SSukumar.Swaminathan@Sun.COM } else if (link_speed == 1) {
40110997SSukumar.Swaminathan@Sun.COM qlge->speed = SPEED_1000;
40210997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link speed 1G\n",
40310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
40410997SSukumar.Swaminathan@Sun.COM } else if (link_speed == 2) {
40510997SSukumar.Swaminathan@Sun.COM qlge->speed = SPEED_10G;
40610997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link speed 10G\n",
40710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
40810997SSukumar.Swaminathan@Sun.COM }
40910997SSukumar.Swaminathan@Sun.COM
41010997SSukumar.Swaminathan@Sun.COM qlge->link_type = link_type = (uint8_t)(link_status & 0x07);
41110997SSukumar.Swaminathan@Sun.COM
41210997SSukumar.Swaminathan@Sun.COM if (link_type == XFI_NETWORK_INTERFACE) {
41310997SSukumar.Swaminathan@Sun.COM /* EMPTY */
41410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
41510997SSukumar.Swaminathan@Sun.COM ("%s(%d):Link type XFI_NETWORK_INTERFACE\n",
41610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
41710997SSukumar.Swaminathan@Sun.COM } else if (link_type == XAUI_NETWORK_INTERFACE) {
41810997SSukumar.Swaminathan@Sun.COM /* EMPTY */
41910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link type"
42010997SSukumar.Swaminathan@Sun.COM "XAUI_NETWORK_INTERFACE\n",
42110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
42210997SSukumar.Swaminathan@Sun.COM } else if (link_type == XFI_BACKPLANE_INTERFACE) {
42310997SSukumar.Swaminathan@Sun.COM /* EMPTY */
42410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link type"
42510997SSukumar.Swaminathan@Sun.COM "XFI_BACKPLANE_INTERFACE\n",
42610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
42710997SSukumar.Swaminathan@Sun.COM } else if (link_type == XAUI_BACKPLANE_INTERFACE) {
42810997SSukumar.Swaminathan@Sun.COM /* EMPTY */
42910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d):Link type "
43010997SSukumar.Swaminathan@Sun.COM "XAUI_BACKPLANE_INTERFACE\n",
43110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
43210997SSukumar.Swaminathan@Sun.COM } else if (link_type == EXT_10GBASE_T_PHY) {
43310997SSukumar.Swaminathan@Sun.COM /* EMPTY */
43410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
43510997SSukumar.Swaminathan@Sun.COM ("%s(%d):Link type EXT_10GBASE_T_PHY\n",
43610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
43710997SSukumar.Swaminathan@Sun.COM } else if (link_type == EXT_EXT_EDC_PHY) {
43810997SSukumar.Swaminathan@Sun.COM /* EMPTY */
43910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
44010997SSukumar.Swaminathan@Sun.COM ("%s(%d):Link type EXT_EXT_EDC_PHY\n",
44110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
44210997SSukumar.Swaminathan@Sun.COM } else {
44310997SSukumar.Swaminathan@Sun.COM /* EMPTY */
44410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
44510997SSukumar.Swaminathan@Sun.COM ("%s(%d):unknown Link type \n",
44610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
44710997SSukumar.Swaminathan@Sun.COM }
44812073SSukumar.Swaminathan@Sun.COM cmn_err(CE_NOTE, "qlge(%d) mpi link up! speed %dMbps\n",
44912073SSukumar.Swaminathan@Sun.COM qlge->instance, qlge->speed);
45010997SSukumar.Swaminathan@Sun.COM /*
45110997SSukumar.Swaminathan@Sun.COM * start timer if not started to delay some time then
45210997SSukumar.Swaminathan@Sun.COM * check if link is really up or down
45310997SSukumar.Swaminathan@Sun.COM */
45410997SSukumar.Swaminathan@Sun.COM ql_restart_timer(qlge);
45510997SSukumar.Swaminathan@Sun.COM
45610997SSukumar.Swaminathan@Sun.COM break;
45710997SSukumar.Swaminathan@Sun.COM case MBA_LINK_DOWN /* 8012h */:
45810997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
45910997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_LINK_DOWN received\n",
46010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
46110997SSukumar.Swaminathan@Sun.COM
46210997SSukumar.Swaminathan@Sun.COM link_status = mbx_cmds->mb[1];
46310997SSukumar.Swaminathan@Sun.COM
46410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): Link Status %x \n",
46510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, link_status));
46610997SSukumar.Swaminathan@Sun.COM if (link_status & 0x1) {
46710997SSukumar.Swaminathan@Sun.COM /* EMPTY */
46810997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): Loss of signal \n",
46910997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
47010997SSukumar.Swaminathan@Sun.COM }
47110997SSukumar.Swaminathan@Sun.COM if (link_status & 0x2) {
47210997SSukumar.Swaminathan@Sun.COM /* EMPTY */
47310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
47410997SSukumar.Swaminathan@Sun.COM ("%s(%d): Auto-Negotiation Failed \n",
47510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
47610997SSukumar.Swaminathan@Sun.COM }
47710997SSukumar.Swaminathan@Sun.COM if (link_status & 0x4) {
47810997SSukumar.Swaminathan@Sun.COM /* EMPTY */
47910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
48010997SSukumar.Swaminathan@Sun.COM ("%s(%d): XTI-Training Failed \n",
48110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
48210997SSukumar.Swaminathan@Sun.COM }
48310997SSukumar.Swaminathan@Sun.COM
48412073SSukumar.Swaminathan@Sun.COM cmn_err(CE_NOTE, "qlge(%d) mpi link down!\n", qlge->instance);
48510997SSukumar.Swaminathan@Sun.COM ql_restart_timer(qlge);
48610997SSukumar.Swaminathan@Sun.COM break;
48710997SSukumar.Swaminathan@Sun.COM case MBA_IDC_COMPLETE /* 8100h */:
48810997SSukumar.Swaminathan@Sun.COM
48910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
49010997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_IDC_COMPLETE received\n",
49110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
49210997SSukumar.Swaminathan@Sun.COM cmd = mbx_cmds->mb[1];
49310997SSukumar.Swaminathan@Sun.COM if (cmd == MBC_STOP_FIRMWARE) {
49410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
49510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
49610997SSukumar.Swaminathan@Sun.COM ("%s(%d): STOP_FIRMWARE event completed\n",
49710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
49810997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_IDC_REQUEST) {
49910997SSukumar.Swaminathan@Sun.COM /* EMPTY */
50010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
50110997SSukumar.Swaminathan@Sun.COM ("%s(%d): IDC_REQUEST event completed\n",
50210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
50310997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_PORT_RESET) {
50410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
50510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
50610997SSukumar.Swaminathan@Sun.COM ("%s(%d): PORT_RESET event completed\n",
50710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
50810997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_SET_PORT_CONFIG) {
50910997SSukumar.Swaminathan@Sun.COM /* EMPTY */
51010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
51110997SSukumar.Swaminathan@Sun.COM ("%s(%d): SET_PORT_CONFIG event "
51210997SSukumar.Swaminathan@Sun.COM "completed\n", __func__, qlge->instance));
51310997SSukumar.Swaminathan@Sun.COM } else {
51410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
51510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
51610997SSukumar.Swaminathan@Sun.COM ("%s(%d): unknown IDC completion request"
51710997SSukumar.Swaminathan@Sun.COM " event %x %x\n", __func__, qlge->instance,
51810997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[1], mbx_cmds->mb[2]));
51910997SSukumar.Swaminathan@Sun.COM }
52010997SSukumar.Swaminathan@Sun.COM proc_done = B_FALSE;
52110997SSukumar.Swaminathan@Sun.COM break;
52210997SSukumar.Swaminathan@Sun.COM
52310997SSukumar.Swaminathan@Sun.COM case MBA_IDC_REQUEST_NOTIFICATION /* 8101h */:
52410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
52510997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_IDC_REQUEST_NOTIFICATION "
52610997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
52710997SSukumar.Swaminathan@Sun.COM cmd = mbx_cmds->mb[1];
52810997SSukumar.Swaminathan@Sun.COM if (cmd == MBC_STOP_FIRMWARE) {
52910997SSukumar.Swaminathan@Sun.COM /* EMPTY */
53010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
53110997SSukumar.Swaminathan@Sun.COM ("%s(%d): STOP_FIRMWARE notification"
53210997SSukumar.Swaminathan@Sun.COM " received\n", __func__, qlge->instance));
53310997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_IDC_REQUEST) {
53410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
53510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
53610997SSukumar.Swaminathan@Sun.COM ("%s(%d): IDC_REQUEST notification "
53710997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
53810997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_PORT_RESET) {
53910997SSukumar.Swaminathan@Sun.COM /* EMPTY */
54010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): PORT_RESET "
54110997SSukumar.Swaminathan@Sun.COM "notification received\n",
54210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
54310997SSukumar.Swaminathan@Sun.COM } else if (cmd == MBC_SET_PORT_CONFIG) {
54410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
54510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
54610997SSukumar.Swaminathan@Sun.COM ("%s(%d): SET_PORT_CONFIG notification "
54710997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
54810997SSukumar.Swaminathan@Sun.COM } else {
54910997SSukumar.Swaminathan@Sun.COM /* EMPTY */
55010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): "
55110997SSukumar.Swaminathan@Sun.COM "unknown request received %x %x\n",
55210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmds->mb[1],
55310997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[2]));
55410997SSukumar.Swaminathan@Sun.COM }
55510997SSukumar.Swaminathan@Sun.COM reply_cmd.mb[0] = MBC_IDC_ACK;
55610997SSukumar.Swaminathan@Sun.COM reply_cmd.mb[1] = mbx_cmds->mb[1];
55710997SSukumar.Swaminathan@Sun.COM reply_cmd.mb[2] = mbx_cmds->mb[2];
55810997SSukumar.Swaminathan@Sun.COM reply_cmd.mb[3] = mbx_cmds->mb[3];
55910997SSukumar.Swaminathan@Sun.COM reply_cmd.mb[4] = mbx_cmds->mb[4];
56010997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd(qlge, &reply_cmd)
56110997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
56210997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
56310997SSukumar.Swaminathan@Sun.COM "%s(%d) send IDC Ack failed.",
56410997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
56510997SSukumar.Swaminathan@Sun.COM }
56610997SSukumar.Swaminathan@Sun.COM /*
56710997SSukumar.Swaminathan@Sun.COM * verify if the incoming outbound mailbox value is what
56810997SSukumar.Swaminathan@Sun.COM * we just sent
56910997SSukumar.Swaminathan@Sun.COM */
57010997SSukumar.Swaminathan@Sun.COM if (mbx_cmds->mb[0] == MBS_COMMAND_COMPLETE) {
57110997SSukumar.Swaminathan@Sun.COM /* 0x4000 */
57210997SSukumar.Swaminathan@Sun.COM /* EMPTY */
57310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
57410997SSukumar.Swaminathan@Sun.COM ("%s(%d): IDC Ack sent success.\n",
57510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
57610997SSukumar.Swaminathan@Sun.COM } else {
57710997SSukumar.Swaminathan@Sun.COM /* EMPTY */
57810997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
57910997SSukumar.Swaminathan@Sun.COM ("%s(%d): IDC Ack reply error %x %x %x.\n",
58010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmds->mb[0],
58110997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[1], mbx_cmds->mb[2]));
58210997SSukumar.Swaminathan@Sun.COM }
58310997SSukumar.Swaminathan@Sun.COM break;
58410997SSukumar.Swaminathan@Sun.COM case MBA_IDC_TIME_EXTENDED /* 8102 */:
58510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
58610997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_IDC_TIME_EXTENDED received\n",
58710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
58810997SSukumar.Swaminathan@Sun.COM break;
58910997SSukumar.Swaminathan@Sun.COM case MBA_DCBX_CONFIG_CHANGE /* 8110 */:
59010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
59110997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_DCBX_CONFIG_CHANGE received\n",
59210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
59310997SSukumar.Swaminathan@Sun.COM break;
59410997SSukumar.Swaminathan@Sun.COM case MBA_NOTIFICATION_LOST /* 8120 */:
59510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
59610997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_NOTIFICATION_LOST received\n",
59710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
59810997SSukumar.Swaminathan@Sun.COM break;
59910997SSukumar.Swaminathan@Sun.COM case MBA_SFT_TRANSCEIVER_INSERTION /* 8130 */:
60010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
60110997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_SFT_TRANSCEIVER_INSERTION "
60210997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
60310997SSukumar.Swaminathan@Sun.COM break;
60410997SSukumar.Swaminathan@Sun.COM case MBA_SFT_TRANSCEIVER_REMOVAL /* 8140 */:
60510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
60610997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_SFT_TRANSCEIVER_REMOVAL "
60710997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
60810997SSukumar.Swaminathan@Sun.COM break;
60910997SSukumar.Swaminathan@Sun.COM case MBA_FIRMWARE_INIT_COMPLETE /* 8400 */:
61010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
61110997SSukumar.Swaminathan@Sun.COM ("%s(%d): MBA_FIRMWARE_INIT_COMPLETE "
61210997SSukumar.Swaminathan@Sun.COM "received\n", __func__, qlge->instance));
61310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
61410997SSukumar.Swaminathan@Sun.COM ("%s(%d): mbx[1] %x, mbx[2] %x\n", __func__,
61510997SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_cmds->mb[1], mbx_cmds->mb[2]));
61610997SSukumar.Swaminathan@Sun.COM qlge->fw_init_complete = B_TRUE;
61710997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.major_version =
61810997SSukumar.Swaminathan@Sun.COM LSB(MSW(mbx_cmds->mb[1]));
61910997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.minor_version =
62010997SSukumar.Swaminathan@Sun.COM MSB(LSW(mbx_cmds->mb[1]));
62110997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.sub_minor_version =
62210997SSukumar.Swaminathan@Sun.COM LSB(LSW(mbx_cmds->mb[1]));
62310997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.major_version =
62410997SSukumar.Swaminathan@Sun.COM LSB(MSW(mbx_cmds->mb[2]));
62510997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.minor_version =
62610997SSukumar.Swaminathan@Sun.COM MSB(LSW(mbx_cmds->mb[2]));
62710997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.sub_minor_version =
62810997SSukumar.Swaminathan@Sun.COM LSB(LSW(mbx_cmds->mb[2]));
62910997SSukumar.Swaminathan@Sun.COM break;
63010997SSukumar.Swaminathan@Sun.COM case MBA_FIRMWARE_INIT_FAILED /* 8401 */:
63110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d):"
63210997SSukumar.Swaminathan@Sun.COM "ASYNC_EVENT_FIRMWARE_INIT_FAILURE "
63310997SSukumar.Swaminathan@Sun.COM "received: mbx[1] %x, mbx[2] %x",
63410997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance,
63510997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[1], mbx_cmds->mb[2]);
63612073SSukumar.Swaminathan@Sun.COM fatal_error = B_TRUE;
63710997SSukumar.Swaminathan@Sun.COM break;
63810997SSukumar.Swaminathan@Sun.COM default:
63910997SSukumar.Swaminathan@Sun.COM if (mbx_cmds->mb[0] > 0x8000) {
64010997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d): "
64110997SSukumar.Swaminathan@Sun.COM "Unknown Async event received: mbx[0] %x ,"
64210997SSukumar.Swaminathan@Sun.COM "mbx[1] %x; mbx[2] %x",
64310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance,
64410997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[0], mbx_cmds->mb[1],
64510997SSukumar.Swaminathan@Sun.COM mbx_cmds->mb[2]);
64610997SSukumar.Swaminathan@Sun.COM proc_done = B_TRUE;
64710997SSukumar.Swaminathan@Sun.COM } else {
64810997SSukumar.Swaminathan@Sun.COM proc_done = B_FALSE;
64910997SSukumar.Swaminathan@Sun.COM }
65010997SSukumar.Swaminathan@Sun.COM break;
65110997SSukumar.Swaminathan@Sun.COM }
65212073SSukumar.Swaminathan@Sun.COM if (fatal_error) {
65312073SSukumar.Swaminathan@Sun.COM if (qlge->fm_enable) {
65412073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
65512073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
65612073SSukumar.Swaminathan@Sun.COM atomic_or_32(&qlge->flags, ADAPTER_ERROR);
65712073SSukumar.Swaminathan@Sun.COM }
65812073SSukumar.Swaminathan@Sun.COM }
65910997SSukumar.Swaminathan@Sun.COM return (proc_done);
66010997SSukumar.Swaminathan@Sun.COM }
66110997SSukumar.Swaminathan@Sun.COM
66210997SSukumar.Swaminathan@Sun.COM
66310997SSukumar.Swaminathan@Sun.COM /*
66410997SSukumar.Swaminathan@Sun.COM * MPI Interrupt handler
66510997SSukumar.Swaminathan@Sun.COM * Caller must have MBX_LOCK
66610997SSukumar.Swaminathan@Sun.COM */
66710997SSukumar.Swaminathan@Sun.COM void
ql_do_mpi_intr(qlge_t * qlge)66810997SSukumar.Swaminathan@Sun.COM ql_do_mpi_intr(qlge_t *qlge)
66910997SSukumar.Swaminathan@Sun.COM {
67010997SSukumar.Swaminathan@Sun.COM /*
67110997SSukumar.Swaminathan@Sun.COM * we just need to read first few mailboxes that this adapter's MPI
67210997SSukumar.Swaminathan@Sun.COM * will write response to.
67310997SSukumar.Swaminathan@Sun.COM */
67410997SSukumar.Swaminathan@Sun.COM mutex_enter(&qlge->mbx_mutex);
67510997SSukumar.Swaminathan@Sun.COM
67611016SSukumar.Swaminathan@Sun.COM (void) ql_read_mailbox_cmd(qlge, &qlge->received_mbx_cmds,
67711016SSukumar.Swaminathan@Sun.COM qlge->max_read_mbx);
67810997SSukumar.Swaminathan@Sun.COM
67910997SSukumar.Swaminathan@Sun.COM /*
68010997SSukumar.Swaminathan@Sun.COM * process PI interrupt as async events, if not done,
68110997SSukumar.Swaminathan@Sun.COM * then pass to mailbox processing
68210997SSukumar.Swaminathan@Sun.COM */
68310997SSukumar.Swaminathan@Sun.COM if (ql_async_event_parser(qlge, &qlge->received_mbx_cmds) == B_FALSE) {
68410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) mailbox completion interrupt\n",
68510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
68610997SSukumar.Swaminathan@Sun.COM /*
68710997SSukumar.Swaminathan@Sun.COM * If another thread is waiting for the mail box
68810997SSukumar.Swaminathan@Sun.COM * completion event to occur
68910997SSukumar.Swaminathan@Sun.COM */
69010997SSukumar.Swaminathan@Sun.COM if (qlge->mbx_wait_completion == 1) {
69110997SSukumar.Swaminathan@Sun.COM qlge->mbx_wait_completion = 0;
69210997SSukumar.Swaminathan@Sun.COM cv_broadcast(&qlge->cv_mbx_intr);
69310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
69410997SSukumar.Swaminathan@Sun.COM ("%s(%d) mailbox completion signaled \n",
69510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
69610997SSukumar.Swaminathan@Sun.COM }
69710997SSukumar.Swaminathan@Sun.COM }
69810997SSukumar.Swaminathan@Sun.COM /* inform MPI Firmware to clear the interrupt */
69910997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS,
70010997SSukumar.Swaminathan@Sun.COM HOST_CMD_CLEAR_RISC_TO_HOST_INTR /* 0x0A */);
70110997SSukumar.Swaminathan@Sun.COM mutex_exit(&qlge->mbx_mutex);
70210997SSukumar.Swaminathan@Sun.COM ql_enable_completion_interrupt(qlge, 0); /* MPI is on irq 0 */
70310997SSukumar.Swaminathan@Sun.COM }
70410997SSukumar.Swaminathan@Sun.COM
70510997SSukumar.Swaminathan@Sun.COM /*
70610997SSukumar.Swaminathan@Sun.COM * Test if mailbox communication works
70710997SSukumar.Swaminathan@Sun.COM * This is used when Interrupt is not enabled
70810997SSukumar.Swaminathan@Sun.COM */
70910997SSukumar.Swaminathan@Sun.COM int
ql_mbx_test(qlge_t * qlge)71010997SSukumar.Swaminathan@Sun.COM ql_mbx_test(qlge_t *qlge)
71110997SSukumar.Swaminathan@Sun.COM {
71210997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds;
71310997SSukumar.Swaminathan@Sun.COM mbx_data_t mbx_results;
71410997SSukumar.Swaminathan@Sun.COM int i, test_ok = 1;
71510997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
71610997SSukumar.Swaminathan@Sun.COM
71710997SSukumar.Swaminathan@Sun.COM for (i = 0; i < NUM_MAILBOX_REGS; i++)
71810997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[i] = i;
71910997SSukumar.Swaminathan@Sun.COM
72010997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
72110997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
72210997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
72310997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
72410997SSukumar.Swaminathan@Sun.COM goto out;
72510997SSukumar.Swaminathan@Sun.COM }
72610997SSukumar.Swaminathan@Sun.COM
72710997SSukumar.Swaminathan@Sun.COM /* delay for the processor interrupt is received */
72810997SSukumar.Swaminathan@Sun.COM if (ql_poll_processor_intr(qlge, (uint8_t)mbx_cmds.timeout)
72910997SSukumar.Swaminathan@Sun.COM == DDI_SUCCESS) {
73010997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
73110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
73211016SSukumar.Swaminathan@Sun.COM (void) ql_read_mailbox_cmd(qlge, &mbx_results, 0);
73310997SSukumar.Swaminathan@Sun.COM
73410997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS,
73510997SSukumar.Swaminathan@Sun.COM HOST_CMD_CLEAR_RISC_TO_HOST_INTR);
73610997SSukumar.Swaminathan@Sun.COM
73710997SSukumar.Swaminathan@Sun.COM if (mbx_results.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
73810997SSukumar.Swaminathan@Sun.COM test_ok = 0;
73910997SSukumar.Swaminathan@Sun.COM } else {
74010997SSukumar.Swaminathan@Sun.COM for (i = 1; i < NUM_MAILBOX_REGS; i++) {
74110997SSukumar.Swaminathan@Sun.COM if (mbx_results.mb[i] != i) {
74210997SSukumar.Swaminathan@Sun.COM test_ok = 0;
74310997SSukumar.Swaminathan@Sun.COM break;
74410997SSukumar.Swaminathan@Sun.COM }
74510997SSukumar.Swaminathan@Sun.COM }
74610997SSukumar.Swaminathan@Sun.COM }
74710997SSukumar.Swaminathan@Sun.COM if (test_ok) {
74810997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
74910997SSukumar.Swaminathan@Sun.COM } else {
75010997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
75110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
75210997SSukumar.Swaminathan@Sun.COM }
75310997SSukumar.Swaminathan@Sun.COM } else {
75410997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) mailbox testing error: "
75510997SSukumar.Swaminathan@Sun.COM "PI Intr not received ", __func__, qlge->instance);
75610997SSukumar.Swaminathan@Sun.COM }
75710997SSukumar.Swaminathan@Sun.COM out:
75810997SSukumar.Swaminathan@Sun.COM return (rtn_val);
75910997SSukumar.Swaminathan@Sun.COM }
76010997SSukumar.Swaminathan@Sun.COM
76110997SSukumar.Swaminathan@Sun.COM /*
76210997SSukumar.Swaminathan@Sun.COM * ql_mbx_test2
76310997SSukumar.Swaminathan@Sun.COM * Test if mailbox communication works
76410997SSukumar.Swaminathan@Sun.COM * This is used when Interrupt is enabled
76510997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x06h
76610997SSukumar.Swaminathan@Sun.COM */
76710997SSukumar.Swaminathan@Sun.COM int
ql_mbx_test2(qlge_t * qlge)76810997SSukumar.Swaminathan@Sun.COM ql_mbx_test2(qlge_t *qlge)
76910997SSukumar.Swaminathan@Sun.COM {
77010997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
77110997SSukumar.Swaminathan@Sun.COM int i, test_ok = 1;
77210997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
77310997SSukumar.Swaminathan@Sun.COM
77410997SSukumar.Swaminathan@Sun.COM for (i = 0; i < NUM_MAILBOX_REGS; i++)
77510997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[i] = i;
77610997SSukumar.Swaminathan@Sun.COM
77710997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_MAILBOX_REGISTER_TEST; /* 0x06 */
77810997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
77910997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
78010997SSukumar.Swaminathan@Sun.COM "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
78110997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
78210997SSukumar.Swaminathan@Sun.COM goto out;
78310997SSukumar.Swaminathan@Sun.COM }
78410997SSukumar.Swaminathan@Sun.COM
78510997SSukumar.Swaminathan@Sun.COM /* verify if the incoming outbound mailbox value is what we just sent */
78610997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
78710997SSukumar.Swaminathan@Sun.COM test_ok = 0;
78810997SSukumar.Swaminathan@Sun.COM } else {
78910997SSukumar.Swaminathan@Sun.COM for (i = 1; i < qlge->max_read_mbx; i++) {
79010997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[i] != i) {
79110997SSukumar.Swaminathan@Sun.COM test_ok = 0;
79210997SSukumar.Swaminathan@Sun.COM break;
79310997SSukumar.Swaminathan@Sun.COM }
79410997SSukumar.Swaminathan@Sun.COM }
79510997SSukumar.Swaminathan@Sun.COM }
79610997SSukumar.Swaminathan@Sun.COM if (test_ok) {
79710997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
79810997SSukumar.Swaminathan@Sun.COM } else {
79910997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) mailbox test failed!",
80010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
80110997SSukumar.Swaminathan@Sun.COM }
80210997SSukumar.Swaminathan@Sun.COM out:
80312073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
80412073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
80512073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
80612073SSukumar.Swaminathan@Sun.COM }
80710997SSukumar.Swaminathan@Sun.COM return (rtn_val);
80810997SSukumar.Swaminathan@Sun.COM }
80910997SSukumar.Swaminathan@Sun.COM
81010997SSukumar.Swaminathan@Sun.COM /*
81110997SSukumar.Swaminathan@Sun.COM * ql_get_fw_state
81210997SSukumar.Swaminathan@Sun.COM * Get fw state.
81310997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x69h
81410997SSukumar.Swaminathan@Sun.COM */
81510997SSukumar.Swaminathan@Sun.COM int
ql_get_fw_state(qlge_t * qlge,uint32_t * fw_state_ptr)81610997SSukumar.Swaminathan@Sun.COM ql_get_fw_state(qlge_t *qlge, uint32_t *fw_state_ptr)
81710997SSukumar.Swaminathan@Sun.COM {
81810997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
81910997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
82010997SSukumar.Swaminathan@Sun.COM
82110997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_GET_FIRMWARE_STATE;
82210997SSukumar.Swaminathan@Sun.COM
82310997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
82410997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
82510997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
82610997SSukumar.Swaminathan@Sun.COM " failed.", __func__, qlge->instance);
82710997SSukumar.Swaminathan@Sun.COM goto out;
82810997SSukumar.Swaminathan@Sun.COM }
82910997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successful */
83010997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
83110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) failed, 0x%x",
83210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmds.mb[0]);
83310997SSukumar.Swaminathan@Sun.COM } else {
83410997SSukumar.Swaminathan@Sun.COM /* EMPTY */
83510997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("firmware state: 0x%x\n", mbx_cmds.mb[1]));
83610997SSukumar.Swaminathan@Sun.COM }
83710997SSukumar.Swaminathan@Sun.COM if (fw_state_ptr != NULL)
83810997SSukumar.Swaminathan@Sun.COM *fw_state_ptr = mbx_cmds.mb[1];
83910997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
84010997SSukumar.Swaminathan@Sun.COM out:
84112073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
84212073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
84312073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
84412073SSukumar.Swaminathan@Sun.COM }
84510997SSukumar.Swaminathan@Sun.COM return (rtn_val);
84610997SSukumar.Swaminathan@Sun.COM }
84710997SSukumar.Swaminathan@Sun.COM
84810997SSukumar.Swaminathan@Sun.COM /*
84910997SSukumar.Swaminathan@Sun.COM * ql_set_IDC_Req
85010997SSukumar.Swaminathan@Sun.COM * Send a IDC Request to firmware to notify all functions
85110997SSukumar.Swaminathan@Sun.COM * or any specific functions on the same port
85210997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x100h
85310997SSukumar.Swaminathan@Sun.COM */
85410997SSukumar.Swaminathan@Sun.COM int
ql_set_IDC_Req(qlge_t * qlge,uint8_t dest_functions,uint8_t timeout)85510997SSukumar.Swaminathan@Sun.COM ql_set_IDC_Req(qlge_t *qlge, uint8_t dest_functions, uint8_t timeout)
85610997SSukumar.Swaminathan@Sun.COM {
85710997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
85810997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
85910997SSukumar.Swaminathan@Sun.COM
86010997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_IDC_REQUEST /* 0x100 */;
86110997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[1] = (timeout<<8) | qlge->func_number;
86210997SSukumar.Swaminathan@Sun.COM
86310997SSukumar.Swaminathan@Sun.COM switch (dest_functions) {
86410997SSukumar.Swaminathan@Sun.COM case IDC_REQ_DEST_FUNC_ALL:
86510997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[1] |= IDC_REQ_ALL_DEST_FUNC_MASK;
86610997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = 0;
86710997SSukumar.Swaminathan@Sun.COM break;
86810997SSukumar.Swaminathan@Sun.COM case IDC_REQ_DEST_FUNC_0:
86910997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_0_MASK;
87010997SSukumar.Swaminathan@Sun.COM break;
87110997SSukumar.Swaminathan@Sun.COM case IDC_REQ_DEST_FUNC_1:
87210997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_1_MASK;
87310997SSukumar.Swaminathan@Sun.COM break;
87410997SSukumar.Swaminathan@Sun.COM case IDC_REQ_DEST_FUNC_2:
87510997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_2_MASK;
87610997SSukumar.Swaminathan@Sun.COM break;
87710997SSukumar.Swaminathan@Sun.COM case IDC_REQ_DEST_FUNC_3:
87810997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = IDC_REQ_DEST_FUNC_3_MASK;
87910997SSukumar.Swaminathan@Sun.COM break;
88010997SSukumar.Swaminathan@Sun.COM default:
88110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "Wrong dest functions %x",
88210997SSukumar.Swaminathan@Sun.COM dest_functions);
88310997SSukumar.Swaminathan@Sun.COM }
88410997SSukumar.Swaminathan@Sun.COM
88510997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
88610997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
88710997SSukumar.Swaminathan@Sun.COM "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
88810997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
88910997SSukumar.Swaminathan@Sun.COM goto out;
89010997SSukumar.Swaminathan@Sun.COM }
89110997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successful */
89210997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] == MBA_IDC_INTERMEDIATE_COMPLETE /* 0x1000 */) {
89310997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) mbx1: 0x%x, mbx2: 0x%x\n",
89410997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance, mbx_cmds.mb[1], mbx_cmds.mb[2]));
89510997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
89610997SSukumar.Swaminathan@Sun.COM } else if (mbx_cmds.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
89710997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) cmd sent succesfully 0x%x\n",
89810997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
89910997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
90010997SSukumar.Swaminathan@Sun.COM } else if (mbx_cmds.mb[0] == MBS_COMMAND_ERROR /* 0x4005 */) {
90110997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) failed: COMMAND_ERROR",
90210997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
90310997SSukumar.Swaminathan@Sun.COM } else if (mbx_cmds.mb[0] == MBS_COMMAND_PARAMETER_ERROR /* 0x4006 */) {
90410997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) failed: COMMAND_PARAMETER_ERROR",
90510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
90610997SSukumar.Swaminathan@Sun.COM } else {
90710997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) unknow result: mbx[0]: 0x%x; mbx[1]:"
90810997SSukumar.Swaminathan@Sun.COM " 0x%x; mbx[2]: 0x%x", __func__, qlge->instance,
90910997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0], mbx_cmds.mb[1], mbx_cmds.mb[2]);
91010997SSukumar.Swaminathan@Sun.COM }
91110997SSukumar.Swaminathan@Sun.COM
91210997SSukumar.Swaminathan@Sun.COM out:
91312073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
91412073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
91512073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
91612073SSukumar.Swaminathan@Sun.COM }
91712073SSukumar.Swaminathan@Sun.COM return (rtn_val);
91810997SSukumar.Swaminathan@Sun.COM }
91910997SSukumar.Swaminathan@Sun.COM
92010997SSukumar.Swaminathan@Sun.COM /*
92110997SSukumar.Swaminathan@Sun.COM * ql_set_mpi_port_config
92210997SSukumar.Swaminathan@Sun.COM * Send new port configuration.to mpi
92310997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x122h
92410997SSukumar.Swaminathan@Sun.COM */
92512073SSukumar.Swaminathan@Sun.COM int
ql_set_mpi_port_config(qlge_t * qlge,port_cfg_info_t new_cfg)92610997SSukumar.Swaminathan@Sun.COM ql_set_mpi_port_config(qlge_t *qlge, port_cfg_info_t new_cfg)
92710997SSukumar.Swaminathan@Sun.COM {
92810997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
92910997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
93010997SSukumar.Swaminathan@Sun.COM
93110997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_SET_PORT_CONFIG /* 0x122 */;
93210997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[1] = new_cfg.link_cfg;
93310997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[2] = new_cfg.max_frame_size;
93410997SSukumar.Swaminathan@Sun.COM
93510997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
93610997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
93710997SSukumar.Swaminathan@Sun.COM " failed.", __func__, qlge->instance);
93810997SSukumar.Swaminathan@Sun.COM goto out;
93910997SSukumar.Swaminathan@Sun.COM }
94010997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successful */
94110997SSukumar.Swaminathan@Sun.COM if ((mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) &&
94210997SSukumar.Swaminathan@Sun.COM (mbx_cmds.mb[0] != MBA_IDC_COMPLETE /* 0x8100 */)) {
94312073SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "set port config (%d) failed, 0x%x",
94412073SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_cmds.mb[0]);
94510997SSukumar.Swaminathan@Sun.COM } else
94610997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
94710997SSukumar.Swaminathan@Sun.COM out:
94812073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
94912073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
95012073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
95112073SSukumar.Swaminathan@Sun.COM }
95210997SSukumar.Swaminathan@Sun.COM return (rtn_val);
95310997SSukumar.Swaminathan@Sun.COM }
95410997SSukumar.Swaminathan@Sun.COM
95510997SSukumar.Swaminathan@Sun.COM int
ql_set_pause_mode(qlge_t * qlge)95612073SSukumar.Swaminathan@Sun.COM ql_set_pause_mode(qlge_t *qlge)
95710997SSukumar.Swaminathan@Sun.COM {
95810997SSukumar.Swaminathan@Sun.COM uint32_t pause_bit_mask = 0x60; /* bit 5-6 */
95910997SSukumar.Swaminathan@Sun.COM
96010997SSukumar.Swaminathan@Sun.COM /* clear pause bits */
96110997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg &= ~pause_bit_mask;
96212073SSukumar.Swaminathan@Sun.COM
96310997SSukumar.Swaminathan@Sun.COM /* set new pause mode */
96410997SSukumar.Swaminathan@Sun.COM if (qlge->pause == PAUSE_MODE_STANDARD)
96510997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg |= STD_PAUSE;
96610997SSukumar.Swaminathan@Sun.COM else if (qlge->pause == PAUSE_MODE_PER_PRIORITY)
96710997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg |= PP_PAUSE;
96810997SSukumar.Swaminathan@Sun.COM
96912073SSukumar.Swaminathan@Sun.COM return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
97012073SSukumar.Swaminathan@Sun.COM }
97112073SSukumar.Swaminathan@Sun.COM
97212073SSukumar.Swaminathan@Sun.COM int
ql_set_loop_back_mode(qlge_t * qlge)97312073SSukumar.Swaminathan@Sun.COM ql_set_loop_back_mode(qlge_t *qlge)
97412073SSukumar.Swaminathan@Sun.COM {
97512073SSukumar.Swaminathan@Sun.COM uint32_t loop_back_bit_mask = 0x0e; /* bit 1-3 */
97612073SSukumar.Swaminathan@Sun.COM
97712073SSukumar.Swaminathan@Sun.COM /* clear loop back bits */
97812073SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg &= ~loop_back_bit_mask;
97910997SSukumar.Swaminathan@Sun.COM /* loop back cfg: bit1-3 */
98010997SSukumar.Swaminathan@Sun.COM if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_PARALLEL)
98110997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL;
98210997SSukumar.Swaminathan@Sun.COM else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL)
98310997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL;
984*13148SSukumar.Swaminathan@Sun.COM else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY)
985*13148SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY;
98610997SSukumar.Swaminathan@Sun.COM
98710997SSukumar.Swaminathan@Sun.COM return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
98810997SSukumar.Swaminathan@Sun.COM
98910997SSukumar.Swaminathan@Sun.COM }
99010997SSukumar.Swaminathan@Sun.COM /*
99110997SSukumar.Swaminathan@Sun.COM * ql_get_port_cfg
99210997SSukumar.Swaminathan@Sun.COM * Get port configuration.
99310997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x123h
99410997SSukumar.Swaminathan@Sun.COM */
99510997SSukumar.Swaminathan@Sun.COM int
ql_get_port_cfg(qlge_t * qlge)99610997SSukumar.Swaminathan@Sun.COM ql_get_port_cfg(qlge_t *qlge)
99710997SSukumar.Swaminathan@Sun.COM {
99810997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
99910997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
100010997SSukumar.Swaminathan@Sun.COM
100110997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_GET_PORT_CONFIG /* 0x123 */;
100210997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds) != DDI_SUCCESS) {
100310997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp"
100410997SSukumar.Swaminathan@Sun.COM " failed.", __func__, qlge->instance);
100510997SSukumar.Swaminathan@Sun.COM goto out;
100610997SSukumar.Swaminathan@Sun.COM }
100710997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successfully */
100810997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
100912073SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "get port config (%d) failed, 0x%x",
101012073SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_cmds.mb[0]);
101110997SSukumar.Swaminathan@Sun.COM } else { /* verify frame size */
101210997SSukumar.Swaminathan@Sun.COM if ((mbx_cmds.mb[2] == NORMAL_FRAME_SIZE) ||
101310997SSukumar.Swaminathan@Sun.COM (mbx_cmds.mb[2] == JUMBO_FRAME_SIZE)) {
101410997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.link_cfg = mbx_cmds.mb[1];
101510997SSukumar.Swaminathan@Sun.COM qlge->port_cfg_info.max_frame_size = mbx_cmds.mb[2];
101610997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("link_cfg: 0x%x, max_frame_size:"
101710997SSukumar.Swaminathan@Sun.COM " %d bytes\n", mbx_cmds.mb[1], mbx_cmds.mb[2]));
101810997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
101910997SSukumar.Swaminathan@Sun.COM } else {
102010997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "bad link_cfg: 0x%x, max_frame_size:"
102110997SSukumar.Swaminathan@Sun.COM " %d bytes", mbx_cmds.mb[1], mbx_cmds.mb[2]);
102210997SSukumar.Swaminathan@Sun.COM }
102310997SSukumar.Swaminathan@Sun.COM }
102410997SSukumar.Swaminathan@Sun.COM out:
102512073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
102612073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
102712073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
102812073SSukumar.Swaminathan@Sun.COM }
102910997SSukumar.Swaminathan@Sun.COM return (rtn_val);
103010997SSukumar.Swaminathan@Sun.COM }
103110997SSukumar.Swaminathan@Sun.COM
103210997SSukumar.Swaminathan@Sun.COM /*
103310997SSukumar.Swaminathan@Sun.COM * qlge_get_link_status
103410997SSukumar.Swaminathan@Sun.COM * Get link status.
103510997SSukumar.Swaminathan@Sun.COM * mailbox cmd:0x124h
103610997SSukumar.Swaminathan@Sun.COM */
103710997SSukumar.Swaminathan@Sun.COM int
qlge_get_link_status(qlge_t * qlge,struct qlnic_link_status_info * link_status_ptr)103810997SSukumar.Swaminathan@Sun.COM qlge_get_link_status(qlge_t *qlge,
103910997SSukumar.Swaminathan@Sun.COM struct qlnic_link_status_info *link_status_ptr)
104010997SSukumar.Swaminathan@Sun.COM {
104110997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
104210997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
104310997SSukumar.Swaminathan@Sun.COM
104410997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_GET_LINK_STATUS /* 0x124 */;
104510997SSukumar.Swaminathan@Sun.COM
104610997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
104710997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
104810997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
104910997SSukumar.Swaminathan@Sun.COM "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
105010997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
105110997SSukumar.Swaminathan@Sun.COM goto out;
105210997SSukumar.Swaminathan@Sun.COM }
105310997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successful */
105410997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
105512073SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "get link status(%d) failed, 0x%x",
105610997SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_cmds.mb[0]);
105710997SSukumar.Swaminathan@Sun.COM } else {
105810997SSukumar.Swaminathan@Sun.COM /* EMPTY */
105910997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX,
106010997SSukumar.Swaminathan@Sun.COM ("link status: status1 : 0x%x, status2 : 0x%x, "
106110997SSukumar.Swaminathan@Sun.COM "status3 : 0x%x\n",
106210997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[1], mbx_cmds.mb[2], mbx_cmds.mb[3]));
106310997SSukumar.Swaminathan@Sun.COM }
106410997SSukumar.Swaminathan@Sun.COM if (link_status_ptr != NULL) {
106510997SSukumar.Swaminathan@Sun.COM link_status_ptr->link_status_info = mbx_cmds.mb[1];
106610997SSukumar.Swaminathan@Sun.COM link_status_ptr->additional_info = mbx_cmds.mb[2];
106710997SSukumar.Swaminathan@Sun.COM link_status_ptr->network_hw_info = mbx_cmds.mb[3];
106810997SSukumar.Swaminathan@Sun.COM link_status_ptr->dcbx_frame_counters_info = mbx_cmds.mb[4];
106910997SSukumar.Swaminathan@Sun.COM link_status_ptr->change_counters_info = mbx_cmds.mb[5];
107010997SSukumar.Swaminathan@Sun.COM }
107110997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
107210997SSukumar.Swaminathan@Sun.COM out:
107312073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
107412073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
107512073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
107612073SSukumar.Swaminathan@Sun.COM }
107710997SSukumar.Swaminathan@Sun.COM return (rtn_val);
107810997SSukumar.Swaminathan@Sun.COM }
107910997SSukumar.Swaminathan@Sun.COM
108010997SSukumar.Swaminathan@Sun.COM /*
108110997SSukumar.Swaminathan@Sun.COM * ql_get_firmware_version
108210997SSukumar.Swaminathan@Sun.COM * Get firmware version.
108310997SSukumar.Swaminathan@Sun.COM */
108410997SSukumar.Swaminathan@Sun.COM int
ql_get_firmware_version(qlge_t * qlge,struct qlnic_mpi_version_info * mpi_version_ptr)108510997SSukumar.Swaminathan@Sun.COM ql_get_firmware_version(qlge_t *qlge,
108610997SSukumar.Swaminathan@Sun.COM struct qlnic_mpi_version_info *mpi_version_ptr)
108710997SSukumar.Swaminathan@Sun.COM {
108810997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
108910997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
109010997SSukumar.Swaminathan@Sun.COM
109110997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_ABOUT_FIRMWARE /* 0x08 */;
109210997SSukumar.Swaminathan@Sun.COM
109310997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_wait_rsp(qlge, &mbx_cmds)
109410997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
109510997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN,
109610997SSukumar.Swaminathan@Sun.COM "%s(%d) ql_issue_mailbox_cmd_and_wait_rsp failed.",
109710997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
109810997SSukumar.Swaminathan@Sun.COM goto out;
109910997SSukumar.Swaminathan@Sun.COM }
110010997SSukumar.Swaminathan@Sun.COM
110110997SSukumar.Swaminathan@Sun.COM /* verify if the transaction is completed successful */
110210997SSukumar.Swaminathan@Sun.COM if (mbx_cmds.mb[0] != MBS_COMMAND_COMPLETE /* 0x4000 */) {
110312073SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "get firmware version(%d) failed, 0x%x",
110410997SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_cmds.mb[0]);
110510997SSukumar.Swaminathan@Sun.COM } else {
110610997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.major_version =
110710997SSukumar.Swaminathan@Sun.COM LSB(MSW(mbx_cmds.mb[1]));
110810997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.minor_version =
110910997SSukumar.Swaminathan@Sun.COM MSB(LSW(mbx_cmds.mb[1]));
111010997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.sub_minor_version =
111110997SSukumar.Swaminathan@Sun.COM LSB(LSW(mbx_cmds.mb[1]));
111210997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.major_version =
111310997SSukumar.Swaminathan@Sun.COM LSB(MSW(mbx_cmds.mb[2]));
111410997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.minor_version =
111510997SSukumar.Swaminathan@Sun.COM MSB(LSW(mbx_cmds.mb[2]));
111610997SSukumar.Swaminathan@Sun.COM qlge->phy_version_info.sub_minor_version =
111710997SSukumar.Swaminathan@Sun.COM LSB(LSW(mbx_cmds.mb[2]));
111810997SSukumar.Swaminathan@Sun.COM #ifdef QLGE_LOAD_UNLOAD
111910997SSukumar.Swaminathan@Sun.COM cmn_err(CE_NOTE, "firmware version: %d.%d.%d\n",
112010997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.major_version,
112110997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.minor_version,
112210997SSukumar.Swaminathan@Sun.COM qlge->fw_version_info.sub_minor_version);
112310997SSukumar.Swaminathan@Sun.COM #endif
112410997SSukumar.Swaminathan@Sun.COM if (mpi_version_ptr != NULL) {
112510997SSukumar.Swaminathan@Sun.COM mpi_version_ptr->fw_version =
112610997SSukumar.Swaminathan@Sun.COM (qlge->fw_version_info.major_version<<16)
112710997SSukumar.Swaminathan@Sun.COM |(qlge->fw_version_info.minor_version<<8)
112810997SSukumar.Swaminathan@Sun.COM |(qlge->fw_version_info.sub_minor_version);
112910997SSukumar.Swaminathan@Sun.COM mpi_version_ptr->phy_version =
113010997SSukumar.Swaminathan@Sun.COM (qlge->phy_version_info.major_version<<16)
113110997SSukumar.Swaminathan@Sun.COM |(qlge->phy_version_info.minor_version<<8)
113210997SSukumar.Swaminathan@Sun.COM |(qlge->phy_version_info.sub_minor_version);
113310997SSukumar.Swaminathan@Sun.COM }
113410997SSukumar.Swaminathan@Sun.COM }
113510997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
113610997SSukumar.Swaminathan@Sun.COM out:
113712073SSukumar.Swaminathan@Sun.COM if ((rtn_val != DDI_SUCCESS) && qlge->fm_enable) {
113812073SSukumar.Swaminathan@Sun.COM ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
113912073SSukumar.Swaminathan@Sun.COM ddi_fm_service_impact(qlge->dip, DDI_SERVICE_DEGRADED);
114012073SSukumar.Swaminathan@Sun.COM }
114110997SSukumar.Swaminathan@Sun.COM return (rtn_val);
114210997SSukumar.Swaminathan@Sun.COM }
114310997SSukumar.Swaminathan@Sun.COM
114410997SSukumar.Swaminathan@Sun.COM /*
114510997SSukumar.Swaminathan@Sun.COM * Trigger a system error event
114610997SSukumar.Swaminathan@Sun.COM */
114710997SSukumar.Swaminathan@Sun.COM int
ql_trigger_system_error_event(qlge_t * qlge)114810997SSukumar.Swaminathan@Sun.COM ql_trigger_system_error_event(qlge_t *qlge)
114910997SSukumar.Swaminathan@Sun.COM {
115010997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mbx_cmds = {0};
115110997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
115210997SSukumar.Swaminathan@Sun.COM
115310997SSukumar.Swaminathan@Sun.COM mbx_cmds.mb[0] = MBC_GENERATE_SYS_ERROR; /* 0x2A */
115410997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd(qlge, &mbx_cmds) != DDI_SUCCESS) {
115510997SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "%s(%d) ql_issue_mailbox_cmd timeout.",
115610997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance);
115710997SSukumar.Swaminathan@Sun.COM goto out;
115810997SSukumar.Swaminathan@Sun.COM }
115910997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
116010997SSukumar.Swaminathan@Sun.COM out:
116110997SSukumar.Swaminathan@Sun.COM return (rtn_val);
116210997SSukumar.Swaminathan@Sun.COM }
116310997SSukumar.Swaminathan@Sun.COM
116410997SSukumar.Swaminathan@Sun.COM /*
116510997SSukumar.Swaminathan@Sun.COM * Reset the MPI RISC Processor
116610997SSukumar.Swaminathan@Sun.COM */
116710997SSukumar.Swaminathan@Sun.COM int
ql_reset_mpi_risc(qlge_t * qlge)116810997SSukumar.Swaminathan@Sun.COM ql_reset_mpi_risc(qlge_t *qlge)
116910997SSukumar.Swaminathan@Sun.COM {
117010997SSukumar.Swaminathan@Sun.COM int rtn_val = DDI_FAILURE;
117110997SSukumar.Swaminathan@Sun.COM
117210997SSukumar.Swaminathan@Sun.COM /* Reset the MPI Processor */
117310997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_SET_RISC_RESET);
117410997SSukumar.Swaminathan@Sun.COM if (ql_wait_reg_bit(qlge, REG_HOST_CMD_STATUS, RISC_RESET,
117510997SSukumar.Swaminathan@Sun.COM BIT_SET, 0) != DDI_SUCCESS) {
117611023SSukumar.Swaminathan@Sun.COM (void) ql_read_reg(qlge, REG_HOST_CMD_STATUS);
117710997SSukumar.Swaminathan@Sun.COM goto out;
117810997SSukumar.Swaminathan@Sun.COM }
117910997SSukumar.Swaminathan@Sun.COM ql_write_reg(qlge, REG_HOST_CMD_STATUS, HOST_CMD_CLEAR_RISC_RESET);
118010997SSukumar.Swaminathan@Sun.COM rtn_val = DDI_SUCCESS;
118110997SSukumar.Swaminathan@Sun.COM out:
118210997SSukumar.Swaminathan@Sun.COM return (rtn_val);
118310997SSukumar.Swaminathan@Sun.COM }
118410997SSukumar.Swaminathan@Sun.COM
118510997SSukumar.Swaminathan@Sun.COM int
ql_read_risc_ram(qlge_t * qlge,uint32_t risc_address,uint64_t bp,uint32_t word_count)118610997SSukumar.Swaminathan@Sun.COM ql_read_risc_ram(qlge_t *qlge, uint32_t risc_address, uint64_t bp,
118710997SSukumar.Swaminathan@Sun.COM uint32_t word_count)
118810997SSukumar.Swaminathan@Sun.COM {
118910997SSukumar.Swaminathan@Sun.COM int rval = DDI_FAILURE;
119010997SSukumar.Swaminathan@Sun.COM mbx_cmd_t mc = {0};
119110997SSukumar.Swaminathan@Sun.COM mbx_cmd_t *mcp = &mc;
119210997SSukumar.Swaminathan@Sun.COM mbx_data_t mbx_results;
119310997SSukumar.Swaminathan@Sun.COM
119410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): read risc addr:0x%x,"
119510997SSukumar.Swaminathan@Sun.COM "phys_addr %x,%x words\n", __func__, qlge->instance,
119610997SSukumar.Swaminathan@Sun.COM risc_address, bp, word_count));
119710997SSukumar.Swaminathan@Sun.COM if (CFG_IST(qlge, CFG_CHIP_8100)) {
119810997SSukumar.Swaminathan@Sun.COM mcp->mb[0] = MBC_DUMP_RISC_RAM /* 0x0C */;
119910997SSukumar.Swaminathan@Sun.COM mcp->mb[1] = LSW(risc_address);
120010997SSukumar.Swaminathan@Sun.COM mcp->mb[2] = MSW(LSD(bp));
120110997SSukumar.Swaminathan@Sun.COM mcp->mb[3] = LSW(LSD(bp));
120210997SSukumar.Swaminathan@Sun.COM mcp->mb[4] = MSW(word_count);
120310997SSukumar.Swaminathan@Sun.COM mcp->mb[5] = LSW(word_count);
120410997SSukumar.Swaminathan@Sun.COM mcp->mb[6] = MSW(MSD(bp));
120510997SSukumar.Swaminathan@Sun.COM mcp->mb[7] = LSW(MSD(bp));
120610997SSukumar.Swaminathan@Sun.COM mcp->mb[8] = MSW(risc_address);
120710997SSukumar.Swaminathan@Sun.COM }
120810997SSukumar.Swaminathan@Sun.COM mcp->timeout = 10 /* MAILBOX_TOV */;
120910997SSukumar.Swaminathan@Sun.COM
121010997SSukumar.Swaminathan@Sun.COM if (ql_issue_mailbox_cmd_and_poll_rsp(qlge, mcp, &mbx_results)
121110997SSukumar.Swaminathan@Sun.COM != DDI_SUCCESS) {
121210997SSukumar.Swaminathan@Sun.COM goto out;
121310997SSukumar.Swaminathan@Sun.COM } else {
121410997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d) PI Intr received",
121510997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
121610997SSukumar.Swaminathan@Sun.COM if (mbx_results.mb[0] == MBS_COMMAND_COMPLETE /* 0x4000 */) {
121710997SSukumar.Swaminathan@Sun.COM QL_PRINT(DBG_MBX, ("%s(%d): success\n",
121810997SSukumar.Swaminathan@Sun.COM __func__, qlge->instance));
121910997SSukumar.Swaminathan@Sun.COM rval = DDI_SUCCESS;
122010997SSukumar.Swaminathan@Sun.COM } else {
122112073SSukumar.Swaminathan@Sun.COM cmn_err(CE_WARN, "read_risc_ram(%d): failed, status %x",
122212073SSukumar.Swaminathan@Sun.COM qlge->instance, mbx_results.mb[0]);
122310997SSukumar.Swaminathan@Sun.COM }
122410997SSukumar.Swaminathan@Sun.COM }
122510997SSukumar.Swaminathan@Sun.COM out:
122610997SSukumar.Swaminathan@Sun.COM return (rval);
122710997SSukumar.Swaminathan@Sun.COM }
1228