1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte
22*4c3888b8SHans Rosenfeld /* Copyright 2015 QLogic Corporation */
23fcf3ce44SJohn Forte
24fcf3ce44SJohn Forte /*
25*4c3888b8SHans Rosenfeld * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
26fcf3ce44SJohn Forte */
27fcf3ce44SJohn Forte
28fcf3ce44SJohn Forte /*
29fcf3ce44SJohn Forte * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
30fcf3ce44SJohn Forte *
31fcf3ce44SJohn Forte * ***********************************************************************
32fcf3ce44SJohn Forte * * **
33fcf3ce44SJohn Forte * * NOTICE **
34*4c3888b8SHans Rosenfeld * * COPYRIGHT (C) 1996-2015 QLOGIC CORPORATION **
35fcf3ce44SJohn Forte * * ALL RIGHTS RESERVED **
36fcf3ce44SJohn Forte * * **
37fcf3ce44SJohn Forte * ***********************************************************************
38fcf3ce44SJohn Forte *
39fcf3ce44SJohn Forte */
40fcf3ce44SJohn Forte
41fcf3ce44SJohn Forte #include <ql_apps.h>
42fcf3ce44SJohn Forte #include <ql_api.h>
43fcf3ce44SJohn Forte #include <ql_debug.h>
44fcf3ce44SJohn Forte #include <ql_iocb.h>
45fcf3ce44SJohn Forte #include <ql_isr.h>
46fcf3ce44SJohn Forte #include <ql_mbx.h>
47*4c3888b8SHans Rosenfeld #include <ql_nx.h>
48fcf3ce44SJohn Forte #include <ql_xioctl.h>
49fcf3ce44SJohn Forte
50fcf3ce44SJohn Forte /*
51fcf3ce44SJohn Forte * Local data
52fcf3ce44SJohn Forte */
53fcf3ce44SJohn Forte
54fcf3ce44SJohn Forte /*
55fcf3ce44SJohn Forte * Local prototypes
56fcf3ce44SJohn Forte */
57fcf3ce44SJohn Forte static int ql_mailbox_command(ql_adapter_state_t *, mbx_cmd_t *);
58*4c3888b8SHans Rosenfeld static int ql_task_mgmt_iocb(ql_adapter_state_t *, ql_tgt_t *, uint64_t,
59fcf3ce44SJohn Forte uint32_t, uint16_t);
60fcf3ce44SJohn Forte static int ql_abort_cmd_iocb(ql_adapter_state_t *, ql_srb_t *);
61fcf3ce44SJohn Forte static int ql_setup_mbox_dma_transfer(ql_adapter_state_t *, dma_mem_t *,
62fcf3ce44SJohn Forte caddr_t, uint32_t);
63fcf3ce44SJohn Forte static int ql_setup_mbox_dma_resources(ql_adapter_state_t *, dma_mem_t *,
64fcf3ce44SJohn Forte uint32_t);
65fcf3ce44SJohn Forte static void ql_setup_mbox_dma_data(dma_mem_t *, caddr_t);
66fcf3ce44SJohn Forte static void ql_get_mbox_dma_data(dma_mem_t *, caddr_t);
67*4c3888b8SHans Rosenfeld static int ql_init_req_q(ql_adapter_state_t *, ql_request_q_t *, uint16_t);
68*4c3888b8SHans Rosenfeld static int ql_init_rsp_q(ql_adapter_state_t *, ql_response_q_t *, uint16_t);
69fcf3ce44SJohn Forte /*
70fcf3ce44SJohn Forte * ql_mailbox_command
71fcf3ce44SJohn Forte * Issue mailbox command and waits for completion.
72fcf3ce44SJohn Forte *
73fcf3ce44SJohn Forte * Input:
74fcf3ce44SJohn Forte * ha = adapter state pointer.
75fcf3ce44SJohn Forte * mcp = mailbox command parameter structure pointer.
76fcf3ce44SJohn Forte *
77fcf3ce44SJohn Forte * Returns:
78fcf3ce44SJohn Forte * ql local function return status code.
79fcf3ce44SJohn Forte *
80fcf3ce44SJohn Forte * Context:
81fcf3ce44SJohn Forte * Kernel context.
82fcf3ce44SJohn Forte */
83fcf3ce44SJohn Forte static int
ql_mailbox_command(ql_adapter_state_t * vha,mbx_cmd_t * mcp)84fcf3ce44SJohn Forte ql_mailbox_command(ql_adapter_state_t *vha, mbx_cmd_t *mcp)
85fcf3ce44SJohn Forte {
86fcf3ce44SJohn Forte uint16_t cnt;
87fcf3ce44SJohn Forte uint32_t data;
88fcf3ce44SJohn Forte clock_t timer, cv_stat;
89fcf3ce44SJohn Forte int rval;
90fcf3ce44SJohn Forte uint32_t set_flags = 0;
91fcf3ce44SJohn Forte uint32_t reset_flags = 0;
92fcf3ce44SJohn Forte ql_adapter_state_t *ha = vha->pha;
9316dd44c2SDaniel Beauregard int mbx_cmd = mcp->mb[0];
94fcf3ce44SJohn Forte
95*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, cmd=%xh\n", mbx_cmd);
96fcf3ce44SJohn Forte
97fcf3ce44SJohn Forte /* Acquire mailbox register lock. */
98fcf3ce44SJohn Forte MBX_REGISTER_LOCK(ha);
99fcf3ce44SJohn Forte
100fcf3ce44SJohn Forte /* Check for mailbox available, if not wait for signal. */
101*4c3888b8SHans Rosenfeld while (ha->mailbox_flags & MBX_BUSY_FLG) {
102fcf3ce44SJohn Forte if (ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) {
103*4c3888b8SHans Rosenfeld EL(vha, "powerdown availability cmd=%xh\n", mcp->mb[0]);
104fcf3ce44SJohn Forte MBX_REGISTER_UNLOCK(ha);
105fcf3ce44SJohn Forte return (QL_LOCK_TIMEOUT);
106fcf3ce44SJohn Forte }
107*4c3888b8SHans Rosenfeld ha->mailbox_flags = (uint8_t)
108*4c3888b8SHans Rosenfeld (ha->mailbox_flags | MBX_WANT_FLG);
109fcf3ce44SJohn Forte
110fcf3ce44SJohn Forte /* Set timeout after command that is running. */
111*4c3888b8SHans Rosenfeld timer = ha->mailbox_flags & MBX_BUSY_FLG ?
112*4c3888b8SHans Rosenfeld (mcp->timeout + 20) : 2;
113*4c3888b8SHans Rosenfeld timer = timer * drv_usectohz(1000000);
114d3d50737SRafael Vanoni cv_stat = cv_reltimedwait_sig(&ha->cv_mbx_wait,
115d3d50737SRafael Vanoni &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK);
116fcf3ce44SJohn Forte if (cv_stat == -1 || cv_stat == 0) {
117fcf3ce44SJohn Forte /*
118fcf3ce44SJohn Forte * The timeout time 'timer' was
119fcf3ce44SJohn Forte * reached without the condition
120fcf3ce44SJohn Forte * being signaled.
121fcf3ce44SJohn Forte */
122fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
123fcf3ce44SJohn Forte ~MBX_WANT_FLG);
124fcf3ce44SJohn Forte cv_broadcast(&ha->cv_mbx_wait);
125fcf3ce44SJohn Forte
126fcf3ce44SJohn Forte /* Release mailbox register lock. */
127fcf3ce44SJohn Forte MBX_REGISTER_UNLOCK(ha);
128fcf3ce44SJohn Forte
129fcf3ce44SJohn Forte if (cv_stat == 0) {
130fcf3ce44SJohn Forte EL(vha, "waiting for availability aborted, "
131fcf3ce44SJohn Forte "cmd=%xh\n", mcp->mb[0]);
132fcf3ce44SJohn Forte return (QL_ABORTED);
133fcf3ce44SJohn Forte }
134fcf3ce44SJohn Forte EL(vha, "failed availability cmd=%xh\n", mcp->mb[0]);
135fcf3ce44SJohn Forte return (QL_LOCK_TIMEOUT);
136fcf3ce44SJohn Forte }
137fcf3ce44SJohn Forte }
138fcf3ce44SJohn Forte
139fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)(ha->mailbox_flags | MBX_BUSY_FLG);
140fcf3ce44SJohn Forte
141fcf3ce44SJohn Forte /* Structure pointer for return mailbox registers. */
142fcf3ce44SJohn Forte ha->mcp = mcp;
143fcf3ce44SJohn Forte
144fcf3ce44SJohn Forte /* Load mailbox registers. */
145fcf3ce44SJohn Forte data = mcp->out_mb;
146fcf3ce44SJohn Forte for (cnt = 0; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
147fcf3ce44SJohn Forte if (data & MBX_0) {
148eb82ff87SDaniel Beauregard WRT16_IO_REG(ha, mailbox_in[cnt], mcp->mb[cnt]);
149fcf3ce44SJohn Forte }
150fcf3ce44SJohn Forte data >>= 1;
151fcf3ce44SJohn Forte }
152fcf3ce44SJohn Forte
153fcf3ce44SJohn Forte /* Issue set host interrupt command. */
154fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)(ha->mailbox_flags & ~MBX_INTERRUPT);
155*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_82XX)) {
156eb82ff87SDaniel Beauregard WRT32_IO_REG(ha, nx_host_int, NX_MBX_CMD);
157*4c3888b8SHans Rosenfeld } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
158eb82ff87SDaniel Beauregard WRT32_IO_REG(ha, hccr, HC24_SET_HOST_INT);
159eb82ff87SDaniel Beauregard } else {
160eb82ff87SDaniel Beauregard WRT16_IO_REG(ha, hccr, HC_SET_HOST_INT);
161eb82ff87SDaniel Beauregard }
162fcf3ce44SJohn Forte
163fcf3ce44SJohn Forte /* Wait for command to complete. */
164fcf3ce44SJohn Forte if (ha->flags & INTERRUPTS_ENABLED &&
165*4c3888b8SHans Rosenfeld !(ha->task_daemon_flags & TASK_DAEMON_POWERING_DOWN) &&
166fcf3ce44SJohn Forte !ddi_in_panic()) {
167d3d50737SRafael Vanoni timer = mcp->timeout * drv_usectohz(1000000);
168fcf3ce44SJohn Forte while (!(ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT)) &&
169fcf3ce44SJohn Forte !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
170fcf3ce44SJohn Forte
171d3d50737SRafael Vanoni if (cv_reltimedwait(&ha->cv_mbx_intr,
172d3d50737SRafael Vanoni &ha->pha->mbx_mutex, timer, TR_CLOCK_TICK) == -1) {
173fcf3ce44SJohn Forte /*
174fcf3ce44SJohn Forte * The timeout time 'timer' was
175fcf3ce44SJohn Forte * reached without the condition
176fcf3ce44SJohn Forte * being signaled.
177fcf3ce44SJohn Forte */
178*4c3888b8SHans Rosenfeld EL(vha, "reltimedwait expired cmd=%xh\n",
179*4c3888b8SHans Rosenfeld mcp->mb[0]);
180f885d00fSDaniel Beauregard MBX_REGISTER_UNLOCK(ha);
181f885d00fSDaniel Beauregard while (INTERRUPT_PENDING(ha)) {
182f885d00fSDaniel Beauregard (void) ql_isr((caddr_t)ha);
183f885d00fSDaniel Beauregard INTR_LOCK(ha);
184f885d00fSDaniel Beauregard ha->intr_claimed = B_TRUE;
185f885d00fSDaniel Beauregard INTR_UNLOCK(ha);
186f885d00fSDaniel Beauregard }
187f885d00fSDaniel Beauregard MBX_REGISTER_LOCK(ha);
188fcf3ce44SJohn Forte break;
189fcf3ce44SJohn Forte }
190fcf3ce44SJohn Forte }
191fcf3ce44SJohn Forte } else {
192fcf3ce44SJohn Forte /* Release mailbox register lock. */
193fcf3ce44SJohn Forte MBX_REGISTER_UNLOCK(ha);
194fcf3ce44SJohn Forte
195fcf3ce44SJohn Forte /* Acquire interrupt lock. */
196fcf3ce44SJohn Forte for (timer = mcp->timeout * 100; timer; timer--) {
197fcf3ce44SJohn Forte /* Check for pending interrupts. */
198eb82ff87SDaniel Beauregard while (INTERRUPT_PENDING(ha)) {
199fcf3ce44SJohn Forte (void) ql_isr((caddr_t)ha);
200fcf3ce44SJohn Forte INTR_LOCK(ha);
201fcf3ce44SJohn Forte ha->intr_claimed = B_TRUE;
202fcf3ce44SJohn Forte INTR_UNLOCK(ha);
203fcf3ce44SJohn Forte if (ha->mailbox_flags &
204fcf3ce44SJohn Forte (MBX_INTERRUPT | MBX_ABORT) ||
205fcf3ce44SJohn Forte ha->task_daemon_flags & ISP_ABORT_NEEDED) {
206fcf3ce44SJohn Forte break;
207fcf3ce44SJohn Forte }
208fcf3ce44SJohn Forte }
209fcf3ce44SJohn Forte if (ha->mailbox_flags & (MBX_INTERRUPT | MBX_ABORT) ||
210fcf3ce44SJohn Forte ha->task_daemon_flags & ISP_ABORT_NEEDED) {
211fcf3ce44SJohn Forte break;
212fcf3ce44SJohn Forte } else if (!ddi_in_panic() && timer % 101 == 0) {
213fcf3ce44SJohn Forte delay(drv_usectohz(10000));
214fcf3ce44SJohn Forte } else {
215fcf3ce44SJohn Forte drv_usecwait(10000);
216fcf3ce44SJohn Forte }
217fcf3ce44SJohn Forte }
218fcf3ce44SJohn Forte
219fcf3ce44SJohn Forte /* Acquire mailbox register lock. */
220fcf3ce44SJohn Forte MBX_REGISTER_LOCK(ha);
221fcf3ce44SJohn Forte }
222fcf3ce44SJohn Forte
223fcf3ce44SJohn Forte /* Mailbox command timeout? */
224fcf3ce44SJohn Forte if (ha->task_daemon_flags & ISP_ABORT_NEEDED ||
225fcf3ce44SJohn Forte ha->mailbox_flags & MBX_ABORT) {
226fcf3ce44SJohn Forte rval = QL_ABORTED;
227fcf3ce44SJohn Forte } else if ((ha->mailbox_flags & MBX_INTERRUPT) == 0) {
228*4c3888b8SHans Rosenfeld if (!CFG_IST(ha, CFG_CTRL_82XX)) {
229f885d00fSDaniel Beauregard if (CFG_IST(ha, CFG_DUMP_MAILBOX_TIMEOUT)) {
230f885d00fSDaniel Beauregard (void) ql_binary_fw_dump(ha, FALSE);
231f885d00fSDaniel Beauregard }
232f885d00fSDaniel Beauregard EL(vha, "command timeout, isp_abort_needed\n");
233f885d00fSDaniel Beauregard set_flags |= ISP_ABORT_NEEDED;
234fcf3ce44SJohn Forte }
235fcf3ce44SJohn Forte rval = QL_FUNCTION_TIMEOUT;
236fcf3ce44SJohn Forte } else {
237fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)
238fcf3ce44SJohn Forte (ha->mailbox_flags & ~MBX_INTERRUPT);
23916dd44c2SDaniel Beauregard /*
24016dd44c2SDaniel Beauregard * This is the expected completion path so
24116dd44c2SDaniel Beauregard * return the actual mbx cmd completion status.
24216dd44c2SDaniel Beauregard */
243fcf3ce44SJohn Forte rval = mcp->mb[0];
244fcf3ce44SJohn Forte }
245fcf3ce44SJohn Forte
24616dd44c2SDaniel Beauregard /*
24716dd44c2SDaniel Beauregard * Clear outbound to risc mailbox registers per spec. The exception
24816dd44c2SDaniel Beauregard * is on 2200 mailbox 4 and 5 affect the req and resp que indexes
24916dd44c2SDaniel Beauregard * so avoid writing them.
25016dd44c2SDaniel Beauregard */
251*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_22XX)) {
25216dd44c2SDaniel Beauregard data = ((mcp->out_mb & ~(MBX_4 | MBX_5)) >> 1);
25316dd44c2SDaniel Beauregard } else {
25416dd44c2SDaniel Beauregard data = (mcp->out_mb >> 1);
25516dd44c2SDaniel Beauregard }
256fcf3ce44SJohn Forte for (cnt = 1; cnt < ha->reg_off->mbox_cnt && data; cnt++) {
257fcf3ce44SJohn Forte if (data & MBX_0) {
258eb82ff87SDaniel Beauregard WRT16_IO_REG(ha, mailbox_in[cnt], (uint16_t)0);
259fcf3ce44SJohn Forte }
260fcf3ce44SJohn Forte data >>= 1;
261fcf3ce44SJohn Forte }
262fcf3ce44SJohn Forte
263fcf3ce44SJohn Forte /* Reset busy status. */
264fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
265fcf3ce44SJohn Forte ~(MBX_BUSY_FLG | MBX_ABORT));
266fcf3ce44SJohn Forte ha->mcp = NULL;
267fcf3ce44SJohn Forte
268fcf3ce44SJohn Forte /* If thread is waiting for mailbox go signal it to start. */
269fcf3ce44SJohn Forte if (ha->mailbox_flags & MBX_WANT_FLG) {
270fcf3ce44SJohn Forte ha->mailbox_flags = (uint8_t)(ha->mailbox_flags &
271fcf3ce44SJohn Forte ~MBX_WANT_FLG);
272fcf3ce44SJohn Forte cv_broadcast(&ha->cv_mbx_wait);
273fcf3ce44SJohn Forte }
274fcf3ce44SJohn Forte
275fcf3ce44SJohn Forte /* Release mailbox register lock. */
276fcf3ce44SJohn Forte MBX_REGISTER_UNLOCK(ha);
277fcf3ce44SJohn Forte
278fcf3ce44SJohn Forte if (set_flags != 0 || reset_flags != 0) {
279fcf3ce44SJohn Forte ql_awaken_task_daemon(ha, NULL, set_flags, reset_flags);
280fcf3ce44SJohn Forte }
281fcf3ce44SJohn Forte
282fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
28316dd44c2SDaniel Beauregard EL(vha, "%s failed, rval=%xh, mcp->mb[0]=%xh\n",
28416dd44c2SDaniel Beauregard mbx_cmd_text(mbx_cmd), rval, mcp->mb[0]);
285fcf3ce44SJohn Forte } else {
286fcf3ce44SJohn Forte /*EMPTY*/
287*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
288fcf3ce44SJohn Forte }
289fcf3ce44SJohn Forte
290fcf3ce44SJohn Forte return (rval);
291fcf3ce44SJohn Forte }
292fcf3ce44SJohn Forte
293fcf3ce44SJohn Forte /*
294fcf3ce44SJohn Forte * ql_setup_mbox_dma_resources
295fcf3ce44SJohn Forte * Prepare the data for a mailbox dma transfer.
296fcf3ce44SJohn Forte *
297fcf3ce44SJohn Forte * Input:
298fcf3ce44SJohn Forte * ha = adapter state pointer.
299fcf3ce44SJohn Forte * mem_desc = descriptor to contain the dma resource information.
300fcf3ce44SJohn Forte * data = pointer to the data.
301fcf3ce44SJohn Forte * size = size of the data in bytes.
302fcf3ce44SJohn Forte *
303fcf3ce44SJohn Forte * Returns:
304fcf3ce44SJohn Forte * ql local function return status code.
305fcf3ce44SJohn Forte *
306fcf3ce44SJohn Forte * Context:
307fcf3ce44SJohn Forte * Kernel context.
308fcf3ce44SJohn Forte */
309fcf3ce44SJohn Forte static int
ql_setup_mbox_dma_transfer(ql_adapter_state_t * ha,dma_mem_t * mem_desc,caddr_t data,uint32_t size)310fcf3ce44SJohn Forte ql_setup_mbox_dma_transfer(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
311fcf3ce44SJohn Forte caddr_t data, uint32_t size)
312fcf3ce44SJohn Forte {
313fcf3ce44SJohn Forte int rval = QL_SUCCESS;
314fcf3ce44SJohn Forte
315fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, mem_desc, size)) ==
316fcf3ce44SJohn Forte QL_SUCCESS) {
317fcf3ce44SJohn Forte ql_setup_mbox_dma_data(mem_desc, data);
318fcf3ce44SJohn Forte } else {
319fcf3ce44SJohn Forte EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
320fcf3ce44SJohn Forte }
321fcf3ce44SJohn Forte
322fcf3ce44SJohn Forte return (rval);
323fcf3ce44SJohn Forte }
324fcf3ce44SJohn Forte
325fcf3ce44SJohn Forte /*
326fcf3ce44SJohn Forte * ql_setup_mbox_dma_resources
327fcf3ce44SJohn Forte * Prepare a dma buffer.
328fcf3ce44SJohn Forte *
329fcf3ce44SJohn Forte * Input:
330fcf3ce44SJohn Forte * ha = adapter state pointer.
331fcf3ce44SJohn Forte * mem_desc = descriptor to contain the dma resource information.
332fcf3ce44SJohn Forte * data = pointer to the data.
333fcf3ce44SJohn Forte * size = size of the data in bytes.
334fcf3ce44SJohn Forte *
335fcf3ce44SJohn Forte * Returns:
336fcf3ce44SJohn Forte * ql local function return status code.
337fcf3ce44SJohn Forte *
338fcf3ce44SJohn Forte * Context:
339fcf3ce44SJohn Forte * Kernel context.
340fcf3ce44SJohn Forte */
341fcf3ce44SJohn Forte static int
ql_setup_mbox_dma_resources(ql_adapter_state_t * ha,dma_mem_t * mem_desc,uint32_t size)342fcf3ce44SJohn Forte ql_setup_mbox_dma_resources(ql_adapter_state_t *ha, dma_mem_t *mem_desc,
343fcf3ce44SJohn Forte uint32_t size)
344fcf3ce44SJohn Forte {
345fcf3ce44SJohn Forte int rval = QL_SUCCESS;
346fcf3ce44SJohn Forte
347fcf3ce44SJohn Forte if ((rval = ql_get_dma_mem(ha, mem_desc, size, LITTLE_ENDIAN_DMA,
34816dd44c2SDaniel Beauregard QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
349fcf3ce44SJohn Forte EL(ha, "failed, ql_get_dma_mem FC_NOMEM\n");
350fcf3ce44SJohn Forte rval = QL_MEMORY_ALLOC_FAILED;
351fcf3ce44SJohn Forte }
352fcf3ce44SJohn Forte
353fcf3ce44SJohn Forte return (rval);
354fcf3ce44SJohn Forte }
355fcf3ce44SJohn Forte
356fcf3ce44SJohn Forte /*
357fcf3ce44SJohn Forte * ql_setup_mbox_dma_data
358fcf3ce44SJohn Forte * Move data to the dma buffer.
359fcf3ce44SJohn Forte *
360fcf3ce44SJohn Forte * Input:
361fcf3ce44SJohn Forte * mem_desc = descriptor to contain the dma resource information.
362fcf3ce44SJohn Forte * data = pointer to the data.
363fcf3ce44SJohn Forte *
364fcf3ce44SJohn Forte * Returns:
365fcf3ce44SJohn Forte *
366fcf3ce44SJohn Forte * Context:
367fcf3ce44SJohn Forte * Kernel context.
368fcf3ce44SJohn Forte */
369fcf3ce44SJohn Forte static void
ql_setup_mbox_dma_data(dma_mem_t * mem_desc,caddr_t data)370fcf3ce44SJohn Forte ql_setup_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
371fcf3ce44SJohn Forte {
372fcf3ce44SJohn Forte /* Copy out going data to DMA buffer. */
373fcf3ce44SJohn Forte ddi_rep_put8(mem_desc->acc_handle, (uint8_t *)data,
374fcf3ce44SJohn Forte (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
375fcf3ce44SJohn Forte
376fcf3ce44SJohn Forte /* Sync DMA buffer. */
377fcf3ce44SJohn Forte (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
378fcf3ce44SJohn Forte DDI_DMA_SYNC_FORDEV);
379fcf3ce44SJohn Forte }
380fcf3ce44SJohn Forte
381fcf3ce44SJohn Forte /*
382fcf3ce44SJohn Forte * ql_get_mbox_dma_data
383fcf3ce44SJohn Forte * Recover data from the dma buffer.
384fcf3ce44SJohn Forte *
385fcf3ce44SJohn Forte * Input:
386fcf3ce44SJohn Forte * mem_desc = descriptor to contain the dma resource information.
387fcf3ce44SJohn Forte * data = pointer to the data.
388fcf3ce44SJohn Forte *
389fcf3ce44SJohn Forte * Returns:
390fcf3ce44SJohn Forte *
391fcf3ce44SJohn Forte * Context:
392fcf3ce44SJohn Forte * Kernel context.
393fcf3ce44SJohn Forte */
394fcf3ce44SJohn Forte static void
ql_get_mbox_dma_data(dma_mem_t * mem_desc,caddr_t data)395fcf3ce44SJohn Forte ql_get_mbox_dma_data(dma_mem_t *mem_desc, caddr_t data)
396fcf3ce44SJohn Forte {
397fcf3ce44SJohn Forte /* Sync in coming DMA buffer. */
398fcf3ce44SJohn Forte (void) ddi_dma_sync(mem_desc->dma_handle, 0, mem_desc->size,
399fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
400fcf3ce44SJohn Forte /* Copy in coming DMA data. */
401fcf3ce44SJohn Forte ddi_rep_get8(mem_desc->acc_handle, (uint8_t *)data,
402fcf3ce44SJohn Forte (uint8_t *)mem_desc->bp, mem_desc->size, DDI_DEV_AUTOINCR);
403fcf3ce44SJohn Forte }
404fcf3ce44SJohn Forte
405fcf3ce44SJohn Forte /*
406fcf3ce44SJohn Forte * ql_initialize_ip
407fcf3ce44SJohn Forte * Initialize IP receive buffer queue.
408fcf3ce44SJohn Forte *
409fcf3ce44SJohn Forte * Input:
410fcf3ce44SJohn Forte * ha = adapter state pointer.
411fcf3ce44SJohn Forte * ha->ip_init_ctrl_blk = setup for transmit.
412fcf3ce44SJohn Forte *
413fcf3ce44SJohn Forte * Returns:
414fcf3ce44SJohn Forte * ql local function return status code.
415fcf3ce44SJohn Forte *
416fcf3ce44SJohn Forte * Context:
417fcf3ce44SJohn Forte * Kernel context.
418fcf3ce44SJohn Forte */
419fcf3ce44SJohn Forte int
ql_initialize_ip(ql_adapter_state_t * ha)420fcf3ce44SJohn Forte ql_initialize_ip(ql_adapter_state_t *ha)
421fcf3ce44SJohn Forte {
422fcf3ce44SJohn Forte ql_link_t *link;
423fcf3ce44SJohn Forte ql_tgt_t *tq;
424fcf3ce44SJohn Forte uint16_t index;
425fcf3ce44SJohn Forte int rval;
426fcf3ce44SJohn Forte dma_mem_t mem_desc;
427fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
428fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
429fcf3ce44SJohn Forte
430*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
431fcf3ce44SJohn Forte
432*4c3888b8SHans Rosenfeld if (!CFG_IST(ha, CFG_FCIP_SUPPORT) || ha->vp_index != 0) {
433fcf3ce44SJohn Forte ha->flags &= ~IP_INITIALIZED;
434fcf3ce44SJohn Forte EL(ha, "HBA does not support IP\n");
435fcf3ce44SJohn Forte return (QL_FUNCTION_FAILED);
436fcf3ce44SJohn Forte }
437fcf3ce44SJohn Forte
438*4c3888b8SHans Rosenfeld ha->rcvbuf_ring_ptr = ha->rcv_ring.bp;
439fcf3ce44SJohn Forte ha->rcvbuf_ring_index = 0;
440fcf3ce44SJohn Forte
441fcf3ce44SJohn Forte /* Reset all sequence counts. */
442fcf3ce44SJohn Forte for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
443fcf3ce44SJohn Forte for (link = ha->dev[index].first; link != NULL;
444fcf3ce44SJohn Forte link = link->next) {
445fcf3ce44SJohn Forte tq = link->base_address;
446fcf3ce44SJohn Forte tq->ub_total_seg_cnt = 0;
447fcf3ce44SJohn Forte }
448fcf3ce44SJohn Forte }
449fcf3ce44SJohn Forte
450fcf3ce44SJohn Forte rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
451fcf3ce44SJohn Forte (caddr_t)&ha->ip_init_ctrl_blk, sizeof (ql_comb_ip_init_cb_t));
452fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
453fcf3ce44SJohn Forte EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
454fcf3ce44SJohn Forte return (rval);
455fcf3ce44SJohn Forte }
456fcf3ce44SJohn Forte
457fcf3ce44SJohn Forte mcp->mb[0] = MBC_INITIALIZE_IP;
458fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
459fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
460fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
461fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
462fcf3ce44SJohn Forte mcp->mb[8] = 0;
463fcf3ce44SJohn Forte mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
464fcf3ce44SJohn Forte mcp->in_mb = MBX_8|MBX_0;
465fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
466fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
467fcf3ce44SJohn Forte
468fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
469fcf3ce44SJohn Forte
470fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
471fcf3ce44SJohn Forte ADAPTER_STATE_LOCK(ha);
472fcf3ce44SJohn Forte ha->flags |= IP_INITIALIZED;
473fcf3ce44SJohn Forte ADAPTER_STATE_UNLOCK(ha);
474*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
475fcf3ce44SJohn Forte } else {
476fcf3ce44SJohn Forte ha->flags &= ~IP_INITIALIZED;
477fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
478fcf3ce44SJohn Forte }
479fcf3ce44SJohn Forte return (rval);
480fcf3ce44SJohn Forte }
481fcf3ce44SJohn Forte
482fcf3ce44SJohn Forte /*
483fcf3ce44SJohn Forte * ql_shutdown_ip
484fcf3ce44SJohn Forte * Disconnects firmware IP from system buffers.
485fcf3ce44SJohn Forte *
486fcf3ce44SJohn Forte * Input:
487fcf3ce44SJohn Forte * ha = adapter state pointer.
488fcf3ce44SJohn Forte *
489fcf3ce44SJohn Forte * Returns:
490fcf3ce44SJohn Forte * ql local function return status code.
491fcf3ce44SJohn Forte *
492fcf3ce44SJohn Forte * Context:
493fcf3ce44SJohn Forte * Kernel context.
494fcf3ce44SJohn Forte */
495fcf3ce44SJohn Forte int
ql_shutdown_ip(ql_adapter_state_t * ha)496fcf3ce44SJohn Forte ql_shutdown_ip(ql_adapter_state_t *ha)
497fcf3ce44SJohn Forte {
498fcf3ce44SJohn Forte int rval;
499fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
500fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
501fcf3ce44SJohn Forte fc_unsol_buf_t *ubp;
502fcf3ce44SJohn Forte ql_srb_t *sp;
503fcf3ce44SJohn Forte uint16_t index;
504fcf3ce44SJohn Forte
505*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
506fcf3ce44SJohn Forte
507fcf3ce44SJohn Forte mcp->mb[0] = MBC_UNLOAD_IP;
508fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
509fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
510fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
511fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
512fcf3ce44SJohn Forte
513fcf3ce44SJohn Forte ADAPTER_STATE_LOCK(ha);
514fcf3ce44SJohn Forte QL_UB_LOCK(ha);
515fcf3ce44SJohn Forte /* Return all unsolicited buffers that ISP-IP has. */
516fcf3ce44SJohn Forte for (index = 0; index < QL_UB_LIMIT; index++) {
517fcf3ce44SJohn Forte ubp = ha->ub_array[index];
518fcf3ce44SJohn Forte if (ubp != NULL) {
519fcf3ce44SJohn Forte sp = ubp->ub_fca_private;
520fcf3ce44SJohn Forte sp->flags &= ~SRB_UB_IN_ISP;
521fcf3ce44SJohn Forte }
522fcf3ce44SJohn Forte }
523fcf3ce44SJohn Forte
524fcf3ce44SJohn Forte ha->ub_outcnt = 0;
525fcf3ce44SJohn Forte QL_UB_UNLOCK(ha);
526fcf3ce44SJohn Forte ha->flags &= ~IP_INITIALIZED;
527fcf3ce44SJohn Forte ADAPTER_STATE_UNLOCK(ha);
528fcf3ce44SJohn Forte
529fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
530fcf3ce44SJohn Forte /* EMPTY - no need to check return value of MBC_SHUTDOWN_IP */
531*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
532fcf3ce44SJohn Forte } else {
533fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
534fcf3ce44SJohn Forte }
535fcf3ce44SJohn Forte return (rval);
536fcf3ce44SJohn Forte }
537fcf3ce44SJohn Forte
538fcf3ce44SJohn Forte /*
539fcf3ce44SJohn Forte * ql_online_selftest
540fcf3ce44SJohn Forte * Issue online self test mailbox command.
541fcf3ce44SJohn Forte *
542fcf3ce44SJohn Forte * Input:
543fcf3ce44SJohn Forte * ha = adapter state pointer.
544fcf3ce44SJohn Forte *
545fcf3ce44SJohn Forte * Returns:
546fcf3ce44SJohn Forte * ql local function return status code.
547fcf3ce44SJohn Forte *
548fcf3ce44SJohn Forte * Context:
549fcf3ce44SJohn Forte * Kernel context.
550fcf3ce44SJohn Forte */
551fcf3ce44SJohn Forte int
ql_online_selftest(ql_adapter_state_t * ha)552fcf3ce44SJohn Forte ql_online_selftest(ql_adapter_state_t *ha)
553fcf3ce44SJohn Forte {
554fcf3ce44SJohn Forte int rval;
555fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
556fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
557fcf3ce44SJohn Forte
558*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
559fcf3ce44SJohn Forte
560fcf3ce44SJohn Forte mcp->mb[0] = MBC_ONLINE_SELF_TEST;
561fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
562fcf3ce44SJohn Forte mcp->in_mb = MBX_0 | MBX_1 | MBX_2 | MBX_3;
563fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
564fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
565fcf3ce44SJohn Forte
566fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
567fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
568fcf3ce44SJohn Forte rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
569fcf3ce44SJohn Forte } else {
570fcf3ce44SJohn Forte /*EMPTY*/
571*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
572fcf3ce44SJohn Forte }
573fcf3ce44SJohn Forte return (rval);
574fcf3ce44SJohn Forte }
575fcf3ce44SJohn Forte
576fcf3ce44SJohn Forte /*
577fcf3ce44SJohn Forte * ql_loop_back
578fcf3ce44SJohn Forte * Issue diagnostic loop back frame mailbox command.
579fcf3ce44SJohn Forte *
580fcf3ce44SJohn Forte * Input:
5814f8b8adcSDaniel Beauregard * ha: adapter state pointer.
5824f8b8adcSDaniel Beauregard * findex: FCF index.
5834f8b8adcSDaniel Beauregard * lb: loop back parameter structure pointer.
584fcf3ce44SJohn Forte *
585fcf3ce44SJohn Forte * Returns:
586fcf3ce44SJohn Forte * ql local function return status code.
587fcf3ce44SJohn Forte *
588fcf3ce44SJohn Forte * Context:
589fcf3ce44SJohn Forte * Kernel context.
590fcf3ce44SJohn Forte */
591fcf3ce44SJohn Forte #ifndef apps_64bit
592fcf3ce44SJohn Forte int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb,uint32_t h_xmit,uint32_t h_rcv)5934f8b8adcSDaniel Beauregard ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb,
5944f8b8adcSDaniel Beauregard uint32_t h_xmit, uint32_t h_rcv)
595fcf3ce44SJohn Forte {
596fcf3ce44SJohn Forte int rval;
597fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
598fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
599fcf3ce44SJohn Forte
600*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
601fcf3ce44SJohn Forte
602fcf3ce44SJohn Forte mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
603fcf3ce44SJohn Forte mcp->mb[1] = lb->options;
6044f8b8adcSDaniel Beauregard mcp->mb[2] = findex;
605fcf3ce44SJohn Forte mcp->mb[6] = LSW(h_rcv);
606fcf3ce44SJohn Forte mcp->mb[7] = MSW(h_rcv);
607fcf3ce44SJohn Forte mcp->mb[10] = LSW(lb->transfer_count);
608fcf3ce44SJohn Forte mcp->mb[11] = MSW(lb->transfer_count);
609fcf3ce44SJohn Forte mcp->mb[12] = lb->transfer_segment_count;
610fcf3ce44SJohn Forte mcp->mb[13] = lb->receive_segment_count;
611fcf3ce44SJohn Forte mcp->mb[14] = LSW(lb->transfer_data_address);
612fcf3ce44SJohn Forte mcp->mb[15] = MSW(lb->transfer_data_address);
613fcf3ce44SJohn Forte mcp->mb[16] = LSW(lb->receive_data_address);
614fcf3ce44SJohn Forte mcp->mb[17] = MSW(lb->receive_data_address);
615fcf3ce44SJohn Forte mcp->mb[18] = LSW(lb->iteration_count);
616fcf3ce44SJohn Forte mcp->mb[19] = MSW(lb->iteration_count);
617fcf3ce44SJohn Forte mcp->mb[20] = LSW(h_xmit);
618fcf3ce44SJohn Forte mcp->mb[21] = MSW(h_xmit);
619fcf3ce44SJohn Forte mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
6204f8b8adcSDaniel Beauregard MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
621fcf3ce44SJohn Forte mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
622fcf3ce44SJohn Forte mcp->timeout = lb->iteration_count / 300;
623fcf3ce44SJohn Forte
624fcf3ce44SJohn Forte if (mcp->timeout < MAILBOX_TOV) {
625fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
626fcf3ce44SJohn Forte }
627fcf3ce44SJohn Forte
628fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
629fcf3ce44SJohn Forte
630fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
631eb82ff87SDaniel Beauregard EL(ha, "failed, rval = %xh, mb1=%xh, mb2=%xh, mb3=%xh\n",
632eb82ff87SDaniel Beauregard rval, mcp->mb[1], mcp->mb[2], mcp->mb[3]);
633fcf3ce44SJohn Forte } else {
634fcf3ce44SJohn Forte /*EMPTY*/
635*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
636fcf3ce44SJohn Forte }
637fcf3ce44SJohn Forte return (rval);
638fcf3ce44SJohn Forte }
639fcf3ce44SJohn Forte #else
640fcf3ce44SJohn Forte int
ql_loop_back(ql_adapter_state_t * ha,uint16_t findex,lbp_t * lb)6414f8b8adcSDaniel Beauregard ql_loop_back(ql_adapter_state_t *ha, uint16_t findex, lbp_t *lb)
642fcf3ce44SJohn Forte {
643fcf3ce44SJohn Forte int rval;
644fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
645fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
646fcf3ce44SJohn Forte
647*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
648fcf3ce44SJohn Forte
649fcf3ce44SJohn Forte mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
650fcf3ce44SJohn Forte mcp->mb[1] = lb->options;
6514f8b8adcSDaniel Beauregard mcp->mb[2] = findex;
652fcf3ce44SJohn Forte mcp->mb[6] = LSW(h_rcv);
653fcf3ce44SJohn Forte mcp->mb[7] = MSW(h_rcv);
654fcf3ce44SJohn Forte mcp->mb[6] = LSW(MSD(lb->receive_data_address));
655fcf3ce44SJohn Forte mcp->mb[7] = MSW(MSD(lb->receive_data_address));
656fcf3ce44SJohn Forte mcp->mb[10] = LSW(lb->transfer_count);
657fcf3ce44SJohn Forte mcp->mb[11] = MSW(lb->transfer_count);
658fcf3ce44SJohn Forte mcp->mb[12] = lb->transfer_segment_count;
659fcf3ce44SJohn Forte mcp->mb[13] = lb->receive_segment_count;
660fcf3ce44SJohn Forte mcp->mb[14] = LSW(lb->transfer_data_address);
661fcf3ce44SJohn Forte mcp->mb[15] = MSW(lb->transfer_data_address);
662fcf3ce44SJohn Forte mcp->mb[14] = LSW(LSD(lb->transfer_data_address));
663fcf3ce44SJohn Forte mcp->mb[15] = MSW(LSD(lb->transfer_data_address));
664fcf3ce44SJohn Forte mcp->mb[16] = LSW(lb->receive_data_address);
665fcf3ce44SJohn Forte mcp->mb[17] = MSW(lb->receive_data_address);
666fcf3ce44SJohn Forte mcp->mb[16] = LSW(LSD(lb->receive_data_address));
667fcf3ce44SJohn Forte mcp->mb[17] = MSW(LSD(lb->receive_data_address));
668fcf3ce44SJohn Forte mcp->mb[18] = LSW(lb->iteration_count);
669fcf3ce44SJohn Forte mcp->mb[19] = MSW(lb->iteration_count);
670fcf3ce44SJohn Forte mcp->mb[20] = LSW(h_xmit);
671fcf3ce44SJohn Forte mcp->mb[21] = MSW(h_xmit);
672fcf3ce44SJohn Forte mcp->mb[20] = LSW(MSD(lb->transfer_data_address));
673fcf3ce44SJohn Forte mcp->mb[21] = MSW(MSD(lb->transfer_data_address));
674fcf3ce44SJohn Forte mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
6754f8b8adcSDaniel Beauregard MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
676fcf3ce44SJohn Forte mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
677fcf3ce44SJohn Forte mcp->timeout = lb->iteration_count / 300;
678fcf3ce44SJohn Forte
679fcf3ce44SJohn Forte if (mcp->timeout < MAILBOX_TOV) {
680fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
681fcf3ce44SJohn Forte }
682fcf3ce44SJohn Forte
683fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
684fcf3ce44SJohn Forte
685fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
686fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
687fcf3ce44SJohn Forte } else {
688fcf3ce44SJohn Forte /*EMPTY*/
689*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
690fcf3ce44SJohn Forte }
691fcf3ce44SJohn Forte return (rval);
692fcf3ce44SJohn Forte }
693fcf3ce44SJohn Forte #endif
694fcf3ce44SJohn Forte
695fcf3ce44SJohn Forte /*
696fcf3ce44SJohn Forte * ql_echo
697fcf3ce44SJohn Forte * Issue an ELS echo using the user specified data to a user specified
698fcf3ce44SJohn Forte * destination
699fcf3ce44SJohn Forte *
700fcf3ce44SJohn Forte * Input:
701fcf3ce44SJohn Forte * ha: adapter state pointer.
7024f8b8adcSDaniel Beauregard * findex: FCF index.
703fcf3ce44SJohn Forte * echo_pt: echo parameter structure pointer.
704fcf3ce44SJohn Forte *
705fcf3ce44SJohn Forte * Returns:
706fcf3ce44SJohn Forte * ql local function return status code.
707fcf3ce44SJohn Forte *
708fcf3ce44SJohn Forte * Context:
709fcf3ce44SJohn Forte * Kernel context.
710fcf3ce44SJohn Forte */
711fcf3ce44SJohn Forte int
ql_echo(ql_adapter_state_t * ha,uint16_t findex,echo_t * echo_pt)7124f8b8adcSDaniel Beauregard ql_echo(ql_adapter_state_t *ha, uint16_t findex, echo_t *echo_pt)
713fcf3ce44SJohn Forte {
714fcf3ce44SJohn Forte int rval;
715fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
716fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
717fcf3ce44SJohn Forte
718*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
719fcf3ce44SJohn Forte
720fcf3ce44SJohn Forte mcp->mb[0] = MBC_ECHO; /* ECHO command */
721fcf3ce44SJohn Forte mcp->mb[1] = echo_pt->options; /* command options; 64 bit */
722fcf3ce44SJohn Forte /* addressing (bit 6) and */
723fcf3ce44SJohn Forte /* real echo (bit 15 */
7244f8b8adcSDaniel Beauregard mcp->mb[2] = findex;
725fcf3ce44SJohn Forte
726fcf3ce44SJohn Forte /*
727fcf3ce44SJohn Forte * I know this looks strange, using a field labled "not used"
728fcf3ce44SJohn Forte * The way the ddi_dma_cookie_t structure/union is defined
729fcf3ce44SJohn Forte * is a union of one 64 bit entity with an array of two 32
730fcf3ce44SJohn Forte * bit enititys. Since we have routines to convert 32 bit
731fcf3ce44SJohn Forte * entities into 16 bit entities it is easier to use
732fcf3ce44SJohn Forte * both 32 bit union members then the one 64 bit union
733fcf3ce44SJohn Forte * member
734fcf3ce44SJohn Forte */
735fcf3ce44SJohn Forte if (echo_pt->options & BIT_6) {
736fcf3ce44SJohn Forte /* 64 bit addressing */
737fcf3ce44SJohn Forte /* Receive data dest add in system memory bits 47-32 */
738fcf3ce44SJohn Forte mcp->mb[6] = LSW(echo_pt->receive_data_address.dmac_notused);
739fcf3ce44SJohn Forte
740fcf3ce44SJohn Forte /* Receive data dest add in system memory bits 63-48 */
741fcf3ce44SJohn Forte mcp->mb[7] = MSW(echo_pt->receive_data_address.dmac_notused);
742fcf3ce44SJohn Forte
743fcf3ce44SJohn Forte /* Transmit data source address in system memory bits 47-32 */
744fcf3ce44SJohn Forte mcp->mb[20] = LSW(echo_pt->transfer_data_address.dmac_notused);
745fcf3ce44SJohn Forte
746fcf3ce44SJohn Forte /* Transmit data source address in system memory bits 63-48 */
747fcf3ce44SJohn Forte mcp->mb[21] = MSW(echo_pt->transfer_data_address.dmac_notused);
748fcf3ce44SJohn Forte }
749fcf3ce44SJohn Forte
750fcf3ce44SJohn Forte /* transfer count bits 15-0 */
751fcf3ce44SJohn Forte mcp->mb[10] = LSW(echo_pt->transfer_count);
752fcf3ce44SJohn Forte
753fcf3ce44SJohn Forte /* Transmit data source address in system memory bits 15-0 */
754fcf3ce44SJohn Forte mcp->mb[14] = LSW(echo_pt->transfer_data_address.dmac_address);
755fcf3ce44SJohn Forte
756fcf3ce44SJohn Forte /* Transmit data source address in system memory bits 31-16 */
757fcf3ce44SJohn Forte mcp->mb[15] = MSW(echo_pt->transfer_data_address.dmac_address);
758fcf3ce44SJohn Forte
759fcf3ce44SJohn Forte /* Receive data destination address in system memory bits 15-0 */
760fcf3ce44SJohn Forte mcp->mb[16] = LSW(echo_pt->receive_data_address.dmac_address);
761fcf3ce44SJohn Forte
762fcf3ce44SJohn Forte /* Receive data destination address in system memory bits 31-16 */
763fcf3ce44SJohn Forte mcp->mb[17] = MSW(echo_pt->receive_data_address.dmac_address);
764fcf3ce44SJohn Forte
765fcf3ce44SJohn Forte mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|MBX_14|MBX_10|
7664f8b8adcSDaniel Beauregard MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
7674f8b8adcSDaniel Beauregard mcp->in_mb = MBX_3|MBX_1|MBX_0;
768fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
769fcf3ce44SJohn Forte
770fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
771fcf3ce44SJohn Forte
772fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
773fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
774fcf3ce44SJohn Forte } else {
775fcf3ce44SJohn Forte /*EMPTY*/
776*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
777fcf3ce44SJohn Forte }
778fcf3ce44SJohn Forte return (rval);
779fcf3ce44SJohn Forte }
780fcf3ce44SJohn Forte
781fcf3ce44SJohn Forte /*
782fcf3ce44SJohn Forte * ql_send_change_request
783fcf3ce44SJohn Forte * Issue send change request mailbox command.
784fcf3ce44SJohn Forte *
785fcf3ce44SJohn Forte * Input:
786fcf3ce44SJohn Forte * ha: adapter state pointer.
787fcf3ce44SJohn Forte * fmt: Registration format.
788fcf3ce44SJohn Forte *
789fcf3ce44SJohn Forte * Returns:
790fcf3ce44SJohn Forte * ql local function return status code.
791fcf3ce44SJohn Forte *
792fcf3ce44SJohn Forte * Context:
793fcf3ce44SJohn Forte * Kernel context.
794fcf3ce44SJohn Forte */
795fcf3ce44SJohn Forte int
ql_send_change_request(ql_adapter_state_t * ha,uint16_t fmt)796fcf3ce44SJohn Forte ql_send_change_request(ql_adapter_state_t *ha, uint16_t fmt)
797fcf3ce44SJohn Forte {
798fcf3ce44SJohn Forte int rval;
799fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
800fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
801fcf3ce44SJohn Forte
802*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
803fcf3ce44SJohn Forte
804fcf3ce44SJohn Forte mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
805fcf3ce44SJohn Forte mcp->mb[1] = fmt;
806fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
807fcf3ce44SJohn Forte if (ha->flags & VP_ENABLED) {
808fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
809fcf3ce44SJohn Forte mcp->out_mb |= MBX_9;
810fcf3ce44SJohn Forte }
811fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
812fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
813fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
814fcf3ce44SJohn Forte
815fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
816fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
817fcf3ce44SJohn Forte } else {
818fcf3ce44SJohn Forte /*EMPTY*/
819*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
820fcf3ce44SJohn Forte }
821fcf3ce44SJohn Forte return (rval);
822fcf3ce44SJohn Forte }
823fcf3ce44SJohn Forte
824fcf3ce44SJohn Forte /*
825fcf3ce44SJohn Forte * ql_send_lfa
826fcf3ce44SJohn Forte * Send a Loop Fabric Address mailbox command.
827fcf3ce44SJohn Forte *
828fcf3ce44SJohn Forte * Input:
829fcf3ce44SJohn Forte * ha: adapter state pointer.
830fcf3ce44SJohn Forte * lfa: LFA command structure pointer.
831fcf3ce44SJohn Forte *
832fcf3ce44SJohn Forte * Returns:
833fcf3ce44SJohn Forte * ql local function return status code.
834fcf3ce44SJohn Forte *
835fcf3ce44SJohn Forte * Context:
836fcf3ce44SJohn Forte * Kernel context.
837fcf3ce44SJohn Forte */
838fcf3ce44SJohn Forte int
ql_send_lfa(ql_adapter_state_t * ha,lfa_cmd_t * lfa)839fcf3ce44SJohn Forte ql_send_lfa(ql_adapter_state_t *ha, lfa_cmd_t *lfa)
840fcf3ce44SJohn Forte {
841fcf3ce44SJohn Forte int rval;
842fcf3ce44SJohn Forte uint16_t size;
843fcf3ce44SJohn Forte dma_mem_t mem_desc;
844fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
845fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
846fcf3ce44SJohn Forte
847*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
848fcf3ce44SJohn Forte
849fcf3ce44SJohn Forte /* LFA_CB sz = 4 16bit words subcommand + 10 16bit words header. */
850fcf3ce44SJohn Forte size = (uint16_t)((lfa->subcommand_length[0] + 10) << 1);
851fcf3ce44SJohn Forte
852fcf3ce44SJohn Forte rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, (caddr_t)lfa, size);
853fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
854fcf3ce44SJohn Forte EL(ha, "failed, setup_mbox_dma_transfer: %xh\n", rval);
855fcf3ce44SJohn Forte return (rval);
856fcf3ce44SJohn Forte }
857fcf3ce44SJohn Forte
858fcf3ce44SJohn Forte mcp->mb[0] = MBC_SEND_LFA_COMMAND;
859fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(size >> 1);
860fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
861fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
862fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
863fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
864fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
865fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
866fcf3ce44SJohn Forte if (ha->flags & VP_ENABLED) {
867fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
868fcf3ce44SJohn Forte mcp->out_mb |= MBX_9;
869fcf3ce44SJohn Forte }
870fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
871fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
872fcf3ce44SJohn Forte
873fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
874fcf3ce44SJohn Forte
875fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
876fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
877fcf3ce44SJohn Forte } else {
878fcf3ce44SJohn Forte /*EMPTY*/
879*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
880fcf3ce44SJohn Forte }
881fcf3ce44SJohn Forte
882fcf3ce44SJohn Forte return (rval);
883fcf3ce44SJohn Forte }
884fcf3ce44SJohn Forte
885fcf3ce44SJohn Forte /*
886fcf3ce44SJohn Forte * ql_clear_aca
887fcf3ce44SJohn Forte * Issue clear ACA mailbox command.
888fcf3ce44SJohn Forte *
889fcf3ce44SJohn Forte * Input:
890fcf3ce44SJohn Forte * ha: adapter state pointer.
891fcf3ce44SJohn Forte * tq: target queue pointer.
892*4c3888b8SHans Rosenfeld * lq: LUN queue pointer.
893fcf3ce44SJohn Forte *
894fcf3ce44SJohn Forte * Returns:
895fcf3ce44SJohn Forte * ql local function return status code.
896fcf3ce44SJohn Forte *
897fcf3ce44SJohn Forte * Context:
898fcf3ce44SJohn Forte * Kernel context.
899fcf3ce44SJohn Forte */
900fcf3ce44SJohn Forte int
ql_clear_aca(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)901*4c3888b8SHans Rosenfeld ql_clear_aca(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
902fcf3ce44SJohn Forte {
903fcf3ce44SJohn Forte int rval;
904fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
905fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
906fcf3ce44SJohn Forte
907*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
908fcf3ce44SJohn Forte
909*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
910*4c3888b8SHans Rosenfeld rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
911*4c3888b8SHans Rosenfeld CF_CLEAR_ACA, 0);
912fcf3ce44SJohn Forte } else {
913fcf3ce44SJohn Forte mcp->mb[0] = MBC_CLEAR_ACA;
914fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
915fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
916fcf3ce44SJohn Forte } else {
917fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
918fcf3ce44SJohn Forte }
919*4c3888b8SHans Rosenfeld mcp->mb[2] = lq->lun_no;
920fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
921fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
922fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
923fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
924fcf3ce44SJohn Forte }
925fcf3ce44SJohn Forte
926*4c3888b8SHans Rosenfeld (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
927fcf3ce44SJohn Forte
928fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
929fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
930fcf3ce44SJohn Forte } else {
931fcf3ce44SJohn Forte /*EMPTY*/
932*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
933fcf3ce44SJohn Forte }
934fcf3ce44SJohn Forte
935fcf3ce44SJohn Forte return (rval);
936fcf3ce44SJohn Forte }
937fcf3ce44SJohn Forte
938fcf3ce44SJohn Forte /*
939fcf3ce44SJohn Forte * ql_target_reset
940fcf3ce44SJohn Forte * Issue target reset mailbox command.
941fcf3ce44SJohn Forte *
942fcf3ce44SJohn Forte * Input:
943fcf3ce44SJohn Forte * ha: adapter state pointer.
944fcf3ce44SJohn Forte * tq: target queue pointer.
945fcf3ce44SJohn Forte * delay: seconds.
946fcf3ce44SJohn Forte *
947fcf3ce44SJohn Forte * Returns:
948fcf3ce44SJohn Forte * ql local function return status code.
949fcf3ce44SJohn Forte *
950fcf3ce44SJohn Forte * Context:
951fcf3ce44SJohn Forte * Kernel context.
952fcf3ce44SJohn Forte */
953fcf3ce44SJohn Forte int
ql_target_reset(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t delay)954fcf3ce44SJohn Forte ql_target_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
955fcf3ce44SJohn Forte {
956fcf3ce44SJohn Forte ql_link_t *link;
957*4c3888b8SHans Rosenfeld ql_srb_t *sp;
958fcf3ce44SJohn Forte uint16_t index;
959*4c3888b8SHans Rosenfeld int rval = QL_SUCCESS;
960fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
961fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
962fcf3ce44SJohn Forte
963*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
964*4c3888b8SHans Rosenfeld
965*4c3888b8SHans Rosenfeld ql_requeue_pending_cmds(ha, tq);
966*4c3888b8SHans Rosenfeld INTR_LOCK(ha);
967*4c3888b8SHans Rosenfeld for (index = 1; index < ha->pha->osc_max_cnt; index++) {
968*4c3888b8SHans Rosenfeld if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
969*4c3888b8SHans Rosenfeld sp->lun_queue != NULL &&
970*4c3888b8SHans Rosenfeld sp->lun_queue->target_queue == tq) {
971*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
972*4c3888b8SHans Rosenfeld }
973*4c3888b8SHans Rosenfeld }
974*4c3888b8SHans Rosenfeld INTR_UNLOCK(ha);
975fcf3ce44SJohn Forte
976*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
977fcf3ce44SJohn Forte /* queue = NULL, all targets. */
978fcf3ce44SJohn Forte if (tq == NULL) {
979fcf3ce44SJohn Forte for (index = 0; index < DEVICE_HEAD_LIST_SIZE;
980fcf3ce44SJohn Forte index++) {
981fcf3ce44SJohn Forte for (link = ha->dev[index].first; link !=
982fcf3ce44SJohn Forte NULL; link = link->next) {
983fcf3ce44SJohn Forte tq = link->base_address;
984fcf3ce44SJohn Forte if (!VALID_DEVICE_ID(ha,
985fcf3ce44SJohn Forte tq->loop_id)) {
986fcf3ce44SJohn Forte continue;
987fcf3ce44SJohn Forte }
988c1fad183SDaniel Beauregard
989c1fad183SDaniel Beauregard if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
990c1fad183SDaniel Beauregard rval = ql_task_mgmt_iocb(ha,
991c1fad183SDaniel Beauregard tq, 0, CF_DO_NOT_SEND |
992c1fad183SDaniel Beauregard CF_TARGET_RESET, delay);
993c1fad183SDaniel Beauregard } else {
994c1fad183SDaniel Beauregard rval = ql_task_mgmt_iocb(ha,
995c1fad183SDaniel Beauregard tq, 0, CF_TARGET_RESET,
996c1fad183SDaniel Beauregard delay);
997c1fad183SDaniel Beauregard }
998fcf3ce44SJohn Forte
999fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1000fcf3ce44SJohn Forte break;
1001fcf3ce44SJohn Forte }
1002fcf3ce44SJohn Forte }
1003fcf3ce44SJohn Forte
1004fcf3ce44SJohn Forte if (link != NULL) {
1005fcf3ce44SJohn Forte break;
1006fcf3ce44SJohn Forte }
1007fcf3ce44SJohn Forte }
1008fcf3ce44SJohn Forte tq = NULL;
1009fcf3ce44SJohn Forte } else {
1010c1fad183SDaniel Beauregard
1011c1fad183SDaniel Beauregard if (CFG_IST(ha, CFG_FAST_TIMEOUT)) {
1012c1fad183SDaniel Beauregard rval = ql_task_mgmt_iocb(ha, tq, 0,
1013c1fad183SDaniel Beauregard CF_TARGET_RESET | CF_DO_NOT_SEND, delay);
1014c1fad183SDaniel Beauregard } else {
1015c1fad183SDaniel Beauregard rval = ql_task_mgmt_iocb(ha, tq, 0,
1016c1fad183SDaniel Beauregard CF_TARGET_RESET, delay);
1017c1fad183SDaniel Beauregard }
1018fcf3ce44SJohn Forte }
1019fcf3ce44SJohn Forte } else {
1020fcf3ce44SJohn Forte /* queue = NULL, all targets. */
1021fcf3ce44SJohn Forte if (tq == NULL) {
1022fcf3ce44SJohn Forte mcp->mb[0] = MBC_RESET;
1023fcf3ce44SJohn Forte mcp->mb[1] = delay;
1024fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
1025fcf3ce44SJohn Forte } else {
1026fcf3ce44SJohn Forte mcp->mb[0] = MBC_TARGET_RESET;
1027fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1028fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1029fcf3ce44SJohn Forte } else {
1030fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1031fcf3ce44SJohn Forte }
1032fcf3ce44SJohn Forte mcp->mb[2] = delay;
1033fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
1034fcf3ce44SJohn Forte }
1035fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1036fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1037fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1038fcf3ce44SJohn Forte }
1039fcf3ce44SJohn Forte
1040fcf3ce44SJohn Forte tq == NULL ? (void) ql_marker(ha, 0, 0, MK_SYNC_ALL) :
1041fcf3ce44SJohn Forte (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1042fcf3ce44SJohn Forte
1043fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1044fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
1045fcf3ce44SJohn Forte } else {
1046fcf3ce44SJohn Forte /*EMPTY*/
1047*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1048fcf3ce44SJohn Forte }
1049fcf3ce44SJohn Forte
1050fcf3ce44SJohn Forte return (rval);
1051fcf3ce44SJohn Forte }
1052fcf3ce44SJohn Forte
1053fcf3ce44SJohn Forte /*
1054fcf3ce44SJohn Forte * ql_abort_target
1055fcf3ce44SJohn Forte * Issue abort target mailbox command.
1056fcf3ce44SJohn Forte *
1057fcf3ce44SJohn Forte * Input:
1058fcf3ce44SJohn Forte * ha: adapter state pointer.
1059fcf3ce44SJohn Forte * tq: target queue pointer.
1060fcf3ce44SJohn Forte * delay: in seconds.
1061fcf3ce44SJohn Forte *
1062fcf3ce44SJohn Forte * Returns:
10635dfd244aSDaniel Beauregard * ql local function return status code.
1064fcf3ce44SJohn Forte *
1065fcf3ce44SJohn Forte * Context:
1066fcf3ce44SJohn Forte * Kernel context.
1067fcf3ce44SJohn Forte */
1068fcf3ce44SJohn Forte int
ql_abort_target(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t delay)1069fcf3ce44SJohn Forte ql_abort_target(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t delay)
1070fcf3ce44SJohn Forte {
1071*4c3888b8SHans Rosenfeld ql_srb_t *sp;
1072*4c3888b8SHans Rosenfeld uint16_t index;
1073fcf3ce44SJohn Forte int rval;
1074fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1075fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1076fcf3ce44SJohn Forte
1077*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1078*4c3888b8SHans Rosenfeld
1079*4c3888b8SHans Rosenfeld ql_requeue_pending_cmds(ha, tq);
1080*4c3888b8SHans Rosenfeld INTR_LOCK(ha);
1081*4c3888b8SHans Rosenfeld for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1082*4c3888b8SHans Rosenfeld if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1083*4c3888b8SHans Rosenfeld sp->lun_queue != NULL &&
1084*4c3888b8SHans Rosenfeld sp->lun_queue->target_queue == tq) {
1085*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
1086*4c3888b8SHans Rosenfeld }
1087*4c3888b8SHans Rosenfeld }
1088*4c3888b8SHans Rosenfeld INTR_UNLOCK(ha);
1089fcf3ce44SJohn Forte
1090*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1091fcf3ce44SJohn Forte rval = ql_task_mgmt_iocb(ha, tq, 0,
1092fcf3ce44SJohn Forte CF_DO_NOT_SEND | CF_TARGET_RESET, delay);
1093fcf3ce44SJohn Forte } else {
1094fcf3ce44SJohn Forte mcp->mb[0] = MBC_ABORT_TARGET;
1095fcf3ce44SJohn Forte /* Don't send Task Mgt */
1096fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1097fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1098fcf3ce44SJohn Forte mcp->mb[10] = BIT_0;
1099fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_2|MBX_1|MBX_0;
1100fcf3ce44SJohn Forte } else {
1101fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | BIT_0);
1102fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
1103fcf3ce44SJohn Forte }
1104fcf3ce44SJohn Forte mcp->mb[2] = delay;
1105fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1106fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1107fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1108fcf3ce44SJohn Forte }
1109fcf3ce44SJohn Forte
1110fcf3ce44SJohn Forte (void) ql_marker(ha, tq->loop_id, 0, MK_SYNC_ID);
1111fcf3ce44SJohn Forte
1112fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1113fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1114fcf3ce44SJohn Forte } else {
1115fcf3ce44SJohn Forte /*EMPTY*/
1116*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1117fcf3ce44SJohn Forte }
1118fcf3ce44SJohn Forte return (rval);
1119fcf3ce44SJohn Forte }
1120fcf3ce44SJohn Forte
1121fcf3ce44SJohn Forte /*
1122fcf3ce44SJohn Forte * ql_lun_reset
1123fcf3ce44SJohn Forte * Issue LUN reset task management mailbox command.
1124fcf3ce44SJohn Forte *
1125fcf3ce44SJohn Forte * Input:
1126fcf3ce44SJohn Forte * ha: adapter state pointer.
1127fcf3ce44SJohn Forte * tq: target queue pointer.
1128*4c3888b8SHans Rosenfeld * lq: LUN queue pointer.
1129fcf3ce44SJohn Forte *
1130fcf3ce44SJohn Forte * Returns:
1131fcf3ce44SJohn Forte * ql local function return status code.
1132fcf3ce44SJohn Forte *
1133fcf3ce44SJohn Forte * Context:
1134fcf3ce44SJohn Forte * Kernel context.
1135fcf3ce44SJohn Forte */
1136fcf3ce44SJohn Forte int
ql_lun_reset(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1137*4c3888b8SHans Rosenfeld ql_lun_reset(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1138fcf3ce44SJohn Forte {
1139*4c3888b8SHans Rosenfeld ql_srb_t *sp;
1140*4c3888b8SHans Rosenfeld uint16_t index;
1141fcf3ce44SJohn Forte int rval;
1142fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1143fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1144fcf3ce44SJohn Forte
1145*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1146fcf3ce44SJohn Forte
1147*4c3888b8SHans Rosenfeld ql_requeue_pending_cmds(ha, tq);
1148*4c3888b8SHans Rosenfeld INTR_LOCK(ha);
1149*4c3888b8SHans Rosenfeld for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1150*4c3888b8SHans Rosenfeld if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1151*4c3888b8SHans Rosenfeld sp->lun_queue != NULL &&
1152*4c3888b8SHans Rosenfeld sp->lun_queue->target_queue == tq &&
1153*4c3888b8SHans Rosenfeld sp->lun_queue == lq) {
1154*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
1155*4c3888b8SHans Rosenfeld }
1156*4c3888b8SHans Rosenfeld }
1157*4c3888b8SHans Rosenfeld INTR_UNLOCK(ha);
1158*4c3888b8SHans Rosenfeld
1159*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1160*4c3888b8SHans Rosenfeld rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1161*4c3888b8SHans Rosenfeld CF_LUN_RESET, 0);
1162fcf3ce44SJohn Forte } else {
1163fcf3ce44SJohn Forte mcp->mb[0] = MBC_LUN_RESET;
1164fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1165fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1166fcf3ce44SJohn Forte } else {
1167fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1168fcf3ce44SJohn Forte }
1169*4c3888b8SHans Rosenfeld mcp->mb[2] = lq->lun_no;
1170fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1171fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1172fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1173fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1174fcf3ce44SJohn Forte }
1175fcf3ce44SJohn Forte
1176*4c3888b8SHans Rosenfeld (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1177fcf3ce44SJohn Forte
1178fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1179fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1180fcf3ce44SJohn Forte } else {
1181fcf3ce44SJohn Forte /*EMPTY*/
1182*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1183fcf3ce44SJohn Forte }
1184fcf3ce44SJohn Forte return (rval);
1185fcf3ce44SJohn Forte }
1186fcf3ce44SJohn Forte
1187fcf3ce44SJohn Forte /*
1188fcf3ce44SJohn Forte * ql_clear_task_set
1189fcf3ce44SJohn Forte * Issue clear task set mailbox command.
1190fcf3ce44SJohn Forte *
1191fcf3ce44SJohn Forte * Input:
1192fcf3ce44SJohn Forte * ha: adapter state pointer.
1193fcf3ce44SJohn Forte * tq: target queue pointer.
1194*4c3888b8SHans Rosenfeld * lq: LUN queue pointer.
1195fcf3ce44SJohn Forte *
1196fcf3ce44SJohn Forte * Returns:
1197fcf3ce44SJohn Forte * ql local function return status code.
1198fcf3ce44SJohn Forte *
1199fcf3ce44SJohn Forte * Context:
1200fcf3ce44SJohn Forte * Kernel context.
1201fcf3ce44SJohn Forte */
1202fcf3ce44SJohn Forte int
ql_clear_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1203*4c3888b8SHans Rosenfeld ql_clear_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1204fcf3ce44SJohn Forte {
1205*4c3888b8SHans Rosenfeld ql_srb_t *sp;
1206*4c3888b8SHans Rosenfeld uint16_t index;
1207fcf3ce44SJohn Forte int rval;
1208fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1209fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1210fcf3ce44SJohn Forte
1211*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1212*4c3888b8SHans Rosenfeld
1213*4c3888b8SHans Rosenfeld ql_requeue_pending_cmds(ha, tq);
1214*4c3888b8SHans Rosenfeld INTR_LOCK(ha);
1215*4c3888b8SHans Rosenfeld for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1216*4c3888b8SHans Rosenfeld if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1217*4c3888b8SHans Rosenfeld sp->lun_queue != NULL &&
1218*4c3888b8SHans Rosenfeld sp->lun_queue->target_queue == tq &&
1219*4c3888b8SHans Rosenfeld sp->lun_queue == lq) {
1220*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
1221*4c3888b8SHans Rosenfeld }
1222*4c3888b8SHans Rosenfeld }
1223*4c3888b8SHans Rosenfeld INTR_UNLOCK(ha);
1224fcf3ce44SJohn Forte
1225*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1226*4c3888b8SHans Rosenfeld rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1227*4c3888b8SHans Rosenfeld CF_CLEAR_TASK_SET, 0);
1228fcf3ce44SJohn Forte } else {
1229fcf3ce44SJohn Forte mcp->mb[0] = MBC_CLEAR_TASK_SET;
1230fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1231fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1232fcf3ce44SJohn Forte } else {
1233fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1234fcf3ce44SJohn Forte }
1235*4c3888b8SHans Rosenfeld mcp->mb[2] = lq->lun_no;
1236fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
1237fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1238fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1239fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1240fcf3ce44SJohn Forte }
1241fcf3ce44SJohn Forte
1242*4c3888b8SHans Rosenfeld (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1243fcf3ce44SJohn Forte
1244fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1245fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1246fcf3ce44SJohn Forte } else {
1247fcf3ce44SJohn Forte /*EMPTY*/
1248*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1249fcf3ce44SJohn Forte }
1250fcf3ce44SJohn Forte
1251fcf3ce44SJohn Forte return (rval);
1252fcf3ce44SJohn Forte }
1253fcf3ce44SJohn Forte
1254fcf3ce44SJohn Forte /*
1255fcf3ce44SJohn Forte * ql_abort_task_set
1256fcf3ce44SJohn Forte * Issue abort task set mailbox command.
1257fcf3ce44SJohn Forte *
1258fcf3ce44SJohn Forte * Input:
1259fcf3ce44SJohn Forte * ha: adapter state pointer.
1260fcf3ce44SJohn Forte * tq: target queue pointer.
1261*4c3888b8SHans Rosenfeld * lq: LUN queue pointer.
1262fcf3ce44SJohn Forte *
1263fcf3ce44SJohn Forte * Returns:
1264fcf3ce44SJohn Forte * ql local function return status code.
1265fcf3ce44SJohn Forte *
1266fcf3ce44SJohn Forte * Context:
1267fcf3ce44SJohn Forte * Kernel context.
1268fcf3ce44SJohn Forte */
1269fcf3ce44SJohn Forte int
ql_abort_task_set(ql_adapter_state_t * ha,ql_tgt_t * tq,ql_lun_t * lq)1270*4c3888b8SHans Rosenfeld ql_abort_task_set(ql_adapter_state_t *ha, ql_tgt_t *tq, ql_lun_t *lq)
1271fcf3ce44SJohn Forte {
1272*4c3888b8SHans Rosenfeld ql_srb_t *sp;
1273*4c3888b8SHans Rosenfeld uint16_t index;
1274fcf3ce44SJohn Forte int rval;
1275fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1276fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1277fcf3ce44SJohn Forte
1278*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1279*4c3888b8SHans Rosenfeld
1280*4c3888b8SHans Rosenfeld ql_requeue_pending_cmds(ha, tq);
1281*4c3888b8SHans Rosenfeld INTR_LOCK(ha);
1282*4c3888b8SHans Rosenfeld for (index = 1; index < ha->pha->osc_max_cnt; index++) {
1283*4c3888b8SHans Rosenfeld if ((sp = ha->pha->outstanding_cmds[index]) != NULL &&
1284*4c3888b8SHans Rosenfeld sp->lun_queue != NULL &&
1285*4c3888b8SHans Rosenfeld sp->lun_queue->target_queue == tq &&
1286*4c3888b8SHans Rosenfeld sp->lun_queue == lq) {
1287*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
1288*4c3888b8SHans Rosenfeld }
1289*4c3888b8SHans Rosenfeld }
1290*4c3888b8SHans Rosenfeld INTR_UNLOCK(ha);
1291fcf3ce44SJohn Forte
1292*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1293*4c3888b8SHans Rosenfeld rval = ql_task_mgmt_iocb(ha, tq, lq->lun_addr,
1294*4c3888b8SHans Rosenfeld CF_ABORT_TASK_SET, 0);
1295fcf3ce44SJohn Forte } else {
1296fcf3ce44SJohn Forte mcp->mb[0] = MBC_ABORT_TASK_SET;
1297fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1298fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1299fcf3ce44SJohn Forte } else {
1300fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1301fcf3ce44SJohn Forte }
1302*4c3888b8SHans Rosenfeld mcp->mb[2] = lq->lun_no;
1303fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
1304fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1305fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1306fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1307fcf3ce44SJohn Forte }
1308fcf3ce44SJohn Forte
1309*4c3888b8SHans Rosenfeld (void) ql_marker(ha, tq->loop_id, lq, MK_SYNC_ID);
1310fcf3ce44SJohn Forte
1311fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1312fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1313fcf3ce44SJohn Forte } else {
1314fcf3ce44SJohn Forte /*EMPTY*/
1315*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1316fcf3ce44SJohn Forte }
1317fcf3ce44SJohn Forte
1318fcf3ce44SJohn Forte return (rval);
1319fcf3ce44SJohn Forte }
1320fcf3ce44SJohn Forte
1321fcf3ce44SJohn Forte /*
1322fcf3ce44SJohn Forte * ql_task_mgmt_iocb
1323fcf3ce44SJohn Forte * Function issues task management IOCB.
1324fcf3ce44SJohn Forte *
1325fcf3ce44SJohn Forte * Input:
1326*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
1327*4c3888b8SHans Rosenfeld * tq: target queue pointer.
1328*4c3888b8SHans Rosenfeld * lun_addr: LUN.
1329*4c3888b8SHans Rosenfeld * flags: control flags.
1330*4c3888b8SHans Rosenfeld * delay: seconds.
1331fcf3ce44SJohn Forte *
1332fcf3ce44SJohn Forte * Returns:
1333fcf3ce44SJohn Forte * ql local function return status code.
1334fcf3ce44SJohn Forte *
1335fcf3ce44SJohn Forte * Context:
1336fcf3ce44SJohn Forte * Kernel context
1337fcf3ce44SJohn Forte */
1338fcf3ce44SJohn Forte static int
ql_task_mgmt_iocb(ql_adapter_state_t * ha,ql_tgt_t * tq,uint64_t lun_addr,uint32_t flags,uint16_t delay)1339*4c3888b8SHans Rosenfeld ql_task_mgmt_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint64_t lun_addr,
1340fcf3ce44SJohn Forte uint32_t flags, uint16_t delay)
1341fcf3ce44SJohn Forte {
1342fcf3ce44SJohn Forte ql_mbx_iocb_t *pkt;
1343fcf3ce44SJohn Forte int rval;
1344fcf3ce44SJohn Forte uint32_t pkt_size;
1345*4c3888b8SHans Rosenfeld fcp_ent_addr_t *fcp_ent_addr;
1346fcf3ce44SJohn Forte
1347*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1348fcf3ce44SJohn Forte
1349fcf3ce44SJohn Forte pkt_size = sizeof (ql_mbx_iocb_t);
1350fcf3ce44SJohn Forte pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1351fcf3ce44SJohn Forte if (pkt == NULL) {
1352fcf3ce44SJohn Forte EL(ha, "failed, kmem_zalloc\n");
1353fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
1354fcf3ce44SJohn Forte }
1355fcf3ce44SJohn Forte
1356fcf3ce44SJohn Forte pkt->mgmt.entry_type = TASK_MGMT_TYPE;
1357fcf3ce44SJohn Forte pkt->mgmt.entry_count = 1;
1358fcf3ce44SJohn Forte
1359fcf3ce44SJohn Forte pkt->mgmt.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
1360fcf3ce44SJohn Forte pkt->mgmt.delay = (uint16_t)LE_16(delay);
1361fcf3ce44SJohn Forte pkt->mgmt.timeout = LE_16(MAILBOX_TOV);
1362*4c3888b8SHans Rosenfeld
1363*4c3888b8SHans Rosenfeld fcp_ent_addr = (fcp_ent_addr_t *)&lun_addr;
1364*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[2] = lobyte(fcp_ent_addr->ent_addr_0);
1365*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[3] = hibyte(fcp_ent_addr->ent_addr_0);
1366*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[0] = lobyte(fcp_ent_addr->ent_addr_1);
1367*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[1] = hibyte(fcp_ent_addr->ent_addr_1);
1368*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[6] = lobyte(fcp_ent_addr->ent_addr_2);
1369*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[7] = hibyte(fcp_ent_addr->ent_addr_2);
1370*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[4] = lobyte(fcp_ent_addr->ent_addr_3);
1371*4c3888b8SHans Rosenfeld pkt->mgmt.fcp_lun[5] = hibyte(fcp_ent_addr->ent_addr_3);
1372*4c3888b8SHans Rosenfeld
1373fcf3ce44SJohn Forte pkt->mgmt.control_flags = LE_32(flags);
1374fcf3ce44SJohn Forte pkt->mgmt.target_id[0] = tq->d_id.b.al_pa;
1375fcf3ce44SJohn Forte pkt->mgmt.target_id[1] = tq->d_id.b.area;
1376fcf3ce44SJohn Forte pkt->mgmt.target_id[2] = tq->d_id.b.domain;
1377fcf3ce44SJohn Forte pkt->mgmt.vp_index = ha->vp_index;
1378fcf3ce44SJohn Forte
1379fcf3ce44SJohn Forte rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1380fcf3ce44SJohn Forte if (rval == QL_SUCCESS && (pkt->sts24.entry_status & 0x3c) != 0) {
1381fcf3ce44SJohn Forte EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1382fcf3ce44SJohn Forte pkt->sts24.entry_status, tq->d_id.b24);
1383fcf3ce44SJohn Forte rval = QL_FUNCTION_PARAMETER_ERROR;
1384fcf3ce44SJohn Forte }
1385fcf3ce44SJohn Forte
1386fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&pkt->sts24.comp_status);
1387fcf3ce44SJohn Forte
1388fcf3ce44SJohn Forte if (rval == QL_SUCCESS && pkt->sts24.comp_status != CS_COMPLETE) {
1389fcf3ce44SJohn Forte EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
1390fcf3ce44SJohn Forte pkt->sts24.comp_status, tq->d_id.b24);
1391fcf3ce44SJohn Forte rval = QL_FUNCTION_FAILED;
1392fcf3ce44SJohn Forte }
1393fcf3ce44SJohn Forte
1394fcf3ce44SJohn Forte kmem_free(pkt, pkt_size);
1395fcf3ce44SJohn Forte
1396fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1397fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
1398fcf3ce44SJohn Forte } else {
1399fcf3ce44SJohn Forte /*EMPTY*/
1400*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1401fcf3ce44SJohn Forte }
1402fcf3ce44SJohn Forte
1403fcf3ce44SJohn Forte return (rval);
1404fcf3ce44SJohn Forte }
1405fcf3ce44SJohn Forte
1406fcf3ce44SJohn Forte /*
1407fcf3ce44SJohn Forte * ql_loop_port_bypass
1408fcf3ce44SJohn Forte * Issue loop port bypass mailbox command.
1409fcf3ce44SJohn Forte *
1410fcf3ce44SJohn Forte * Input:
1411fcf3ce44SJohn Forte * ha: adapter state pointer.
1412fcf3ce44SJohn Forte * tq: target queue pointer.
1413fcf3ce44SJohn Forte *
1414fcf3ce44SJohn Forte * Returns:
1415fcf3ce44SJohn Forte * ql local function return status code.
1416fcf3ce44SJohn Forte *
1417fcf3ce44SJohn Forte * Context:
1418fcf3ce44SJohn Forte * Kernel context.
1419fcf3ce44SJohn Forte */
1420fcf3ce44SJohn Forte int
ql_loop_port_bypass(ql_adapter_state_t * ha,ql_tgt_t * tq)1421fcf3ce44SJohn Forte ql_loop_port_bypass(ql_adapter_state_t *ha, ql_tgt_t *tq)
1422fcf3ce44SJohn Forte {
1423fcf3ce44SJohn Forte int rval;
1424fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1425fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1426fcf3ce44SJohn Forte
1427*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1428fcf3ce44SJohn Forte
1429fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOOP_PORT_BYPASS;
1430fcf3ce44SJohn Forte
1431*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1432fcf3ce44SJohn Forte mcp->mb[1] = tq->d_id.b.al_pa;
1433fcf3ce44SJohn Forte } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1434fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1435fcf3ce44SJohn Forte } else {
1436fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1437fcf3ce44SJohn Forte }
1438fcf3ce44SJohn Forte
1439fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
1440fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1441fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1442fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1443fcf3ce44SJohn Forte
1444fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1445fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1446fcf3ce44SJohn Forte } else {
1447fcf3ce44SJohn Forte /*EMPTY*/
1448*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1449fcf3ce44SJohn Forte }
1450fcf3ce44SJohn Forte
1451fcf3ce44SJohn Forte return (rval);
1452fcf3ce44SJohn Forte }
1453fcf3ce44SJohn Forte
1454fcf3ce44SJohn Forte /*
1455fcf3ce44SJohn Forte * ql_loop_port_enable
1456fcf3ce44SJohn Forte * Issue loop port enable mailbox command.
1457fcf3ce44SJohn Forte *
1458fcf3ce44SJohn Forte * Input:
1459fcf3ce44SJohn Forte * ha: adapter state pointer.
1460fcf3ce44SJohn Forte * tq: target queue pointer.
1461fcf3ce44SJohn Forte *
1462fcf3ce44SJohn Forte * Returns:
1463fcf3ce44SJohn Forte * ql local function return status code.
1464fcf3ce44SJohn Forte *
1465fcf3ce44SJohn Forte * Context:
1466fcf3ce44SJohn Forte * Kernel context.
1467fcf3ce44SJohn Forte */
1468fcf3ce44SJohn Forte int
ql_loop_port_enable(ql_adapter_state_t * ha,ql_tgt_t * tq)1469fcf3ce44SJohn Forte ql_loop_port_enable(ql_adapter_state_t *ha, ql_tgt_t *tq)
1470fcf3ce44SJohn Forte {
1471fcf3ce44SJohn Forte int rval;
1472fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1473fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1474fcf3ce44SJohn Forte
1475*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1476fcf3ce44SJohn Forte
1477fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOOP_PORT_ENABLE;
1478fcf3ce44SJohn Forte
1479*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1480fcf3ce44SJohn Forte mcp->mb[1] = tq->d_id.b.al_pa;
1481fcf3ce44SJohn Forte } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1482fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1483fcf3ce44SJohn Forte } else {
1484fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
1485fcf3ce44SJohn Forte }
1486fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
1487fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1488fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1489fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1490fcf3ce44SJohn Forte
1491fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1492fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
1493fcf3ce44SJohn Forte } else {
1494fcf3ce44SJohn Forte /*EMPTY*/
1495*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1496fcf3ce44SJohn Forte }
1497fcf3ce44SJohn Forte
1498fcf3ce44SJohn Forte return (rval);
1499fcf3ce44SJohn Forte }
1500fcf3ce44SJohn Forte
1501fcf3ce44SJohn Forte /*
1502fcf3ce44SJohn Forte * ql_login_lport
1503fcf3ce44SJohn Forte * Issue login loop port mailbox command.
1504fcf3ce44SJohn Forte *
1505fcf3ce44SJohn Forte * Input:
1506fcf3ce44SJohn Forte * ha: adapter state pointer.
1507fcf3ce44SJohn Forte * tq: target queue pointer.
1508fcf3ce44SJohn Forte * loop_id: FC loop id.
1509fcf3ce44SJohn Forte * opt: options.
1510fcf3ce44SJohn Forte * LLF_NONE, LLF_PLOGI
1511fcf3ce44SJohn Forte *
1512fcf3ce44SJohn Forte * Returns:
1513fcf3ce44SJohn Forte * ql local function return status code.
1514fcf3ce44SJohn Forte *
1515fcf3ce44SJohn Forte * Context:
1516fcf3ce44SJohn Forte * Kernel context.
1517fcf3ce44SJohn Forte */
1518fcf3ce44SJohn Forte int
ql_login_lport(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t opt)1519fcf3ce44SJohn Forte ql_login_lport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1520fcf3ce44SJohn Forte uint16_t opt)
1521fcf3ce44SJohn Forte {
1522fcf3ce44SJohn Forte int rval;
1523fcf3ce44SJohn Forte uint16_t flags;
1524fcf3ce44SJohn Forte ql_mbx_data_t mr;
1525fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1526fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1527fcf3ce44SJohn Forte
1528*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1529fcf3ce44SJohn Forte ha->instance, tq->d_id.b24, loop_id);
1530fcf3ce44SJohn Forte
1531*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1532fcf3ce44SJohn Forte flags = CF_CMD_PLOGI;
1533fcf3ce44SJohn Forte if ((opt & LLF_PLOGI) == 0) {
1534fcf3ce44SJohn Forte flags = (uint16_t)(flags | CFO_COND_PLOGI);
1535fcf3ce44SJohn Forte }
1536fcf3ce44SJohn Forte rval = ql_log_iocb(ha, tq, loop_id, flags, &mr);
1537fcf3ce44SJohn Forte } else {
1538fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1539fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1540fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
1541fcf3ce44SJohn Forte } else {
1542fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(loop_id << 8);
1543fcf3ce44SJohn Forte }
1544fcf3ce44SJohn Forte mcp->mb[2] = opt;
1545fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
1546fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1547fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1548fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1549fcf3ce44SJohn Forte }
1550fcf3ce44SJohn Forte
1551fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1552fcf3ce44SJohn Forte EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh\n", tq->d_id.b24,
1553fcf3ce44SJohn Forte loop_id, rval);
1554fcf3ce44SJohn Forte } else {
1555fcf3ce44SJohn Forte /*EMPTY*/
1556*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1557fcf3ce44SJohn Forte }
1558fcf3ce44SJohn Forte
1559fcf3ce44SJohn Forte return (rval);
1560fcf3ce44SJohn Forte }
1561fcf3ce44SJohn Forte
1562fcf3ce44SJohn Forte /*
1563fcf3ce44SJohn Forte * ql_login_fport
1564fcf3ce44SJohn Forte * Issue login fabric port mailbox command.
1565fcf3ce44SJohn Forte *
1566fcf3ce44SJohn Forte * Input:
1567fcf3ce44SJohn Forte * ha: adapter state pointer.
1568fcf3ce44SJohn Forte * tq: target queue pointer.
1569fcf3ce44SJohn Forte * loop_id: FC loop id.
1570fcf3ce44SJohn Forte * opt: options.
1571fcf3ce44SJohn Forte * LFF_NONE, LFF_NO_PLOGI, LFF_NO_PRLI
1572fcf3ce44SJohn Forte * mr: pointer for mailbox data.
1573fcf3ce44SJohn Forte *
1574fcf3ce44SJohn Forte * Returns:
1575fcf3ce44SJohn Forte * ql local function return status code.
1576fcf3ce44SJohn Forte *
1577fcf3ce44SJohn Forte * Context:
1578fcf3ce44SJohn Forte * Kernel context.
1579fcf3ce44SJohn Forte */
1580fcf3ce44SJohn Forte int
ql_login_fport(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t opt,ql_mbx_data_t * mr)1581fcf3ce44SJohn Forte ql_login_fport(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1582fcf3ce44SJohn Forte uint16_t opt, ql_mbx_data_t *mr)
1583fcf3ce44SJohn Forte {
1584fcf3ce44SJohn Forte int rval;
1585fcf3ce44SJohn Forte uint16_t flags;
1586fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1587fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1588fcf3ce44SJohn Forte
1589*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, d_id=%xh, loop_id=%xh\n",
1590fcf3ce44SJohn Forte ha->instance, tq->d_id.b24, loop_id);
1591fcf3ce44SJohn Forte
1592*4c3888b8SHans Rosenfeld if ((tq->d_id.b24 & QL_PORT_ID_MASK) == FS_MANAGEMENT_SERVER) {
1593fcf3ce44SJohn Forte opt = (uint16_t)(opt | LFF_NO_PRLI);
1594fcf3ce44SJohn Forte }
1595fcf3ce44SJohn Forte
1596*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1597fcf3ce44SJohn Forte flags = CF_CMD_PLOGI;
1598fcf3ce44SJohn Forte if (opt & LFF_NO_PLOGI) {
1599fcf3ce44SJohn Forte flags = (uint16_t)(flags | CFO_COND_PLOGI);
1600fcf3ce44SJohn Forte }
1601fcf3ce44SJohn Forte if (opt & LFF_NO_PRLI) {
1602fcf3ce44SJohn Forte flags = (uint16_t)(flags | CFO_SKIP_PRLI);
1603fcf3ce44SJohn Forte }
1604fcf3ce44SJohn Forte rval = ql_log_iocb(ha, tq, loop_id, flags, mr);
1605fcf3ce44SJohn Forte } else {
1606fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1607fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1608fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
1609fcf3ce44SJohn Forte mcp->mb[10] = opt;
1610fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
1611fcf3ce44SJohn Forte } else {
1612fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
1613fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1614fcf3ce44SJohn Forte }
1615fcf3ce44SJohn Forte mcp->mb[2] = MSW(tq->d_id.b24);
1616fcf3ce44SJohn Forte mcp->mb[3] = LSW(tq->d_id.b24);
1617fcf3ce44SJohn Forte mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1618fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1619fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1620fcf3ce44SJohn Forte
1621fcf3ce44SJohn Forte /* Return mailbox data. */
1622fcf3ce44SJohn Forte if (mr != NULL) {
1623fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
1624fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
1625fcf3ce44SJohn Forte mr->mb[2] = mcp->mb[2];
1626fcf3ce44SJohn Forte mr->mb[6] = mcp->mb[6];
1627fcf3ce44SJohn Forte mr->mb[7] = mcp->mb[7];
1628fcf3ce44SJohn Forte }
1629fcf3ce44SJohn Forte }
1630fcf3ce44SJohn Forte
1631fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1632fcf3ce44SJohn Forte EL(ha, "d_id=%xh, loop_id=%xh, failed=%xh, mb1=%02xh, "
1633*4c3888b8SHans Rosenfeld "mb2=%04x\n", tq->d_id.b24, loop_id, rval,
1634*4c3888b8SHans Rosenfeld mr != NULL ? mr->mb[1] : mcp->mb[1],
1635*4c3888b8SHans Rosenfeld mr != NULL ? mr->mb[2] : mcp->mb[2]);
1636fcf3ce44SJohn Forte } else {
1637fcf3ce44SJohn Forte /*EMPTY*/
1638*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1639fcf3ce44SJohn Forte }
1640fcf3ce44SJohn Forte
1641fcf3ce44SJohn Forte return (rval);
1642fcf3ce44SJohn Forte }
1643fcf3ce44SJohn Forte
1644fcf3ce44SJohn Forte /*
1645fcf3ce44SJohn Forte * ql_logout_fabric_port
1646fcf3ce44SJohn Forte * Issue logout fabric port mailbox command.
1647fcf3ce44SJohn Forte *
1648fcf3ce44SJohn Forte * Input:
1649fcf3ce44SJohn Forte * ha: adapter state pointer.
1650fcf3ce44SJohn Forte * tq: target queue pointer.
1651fcf3ce44SJohn Forte *
1652fcf3ce44SJohn Forte * Returns:
1653fcf3ce44SJohn Forte * ql local function return status code.
1654fcf3ce44SJohn Forte *
1655fcf3ce44SJohn Forte * Context:
1656fcf3ce44SJohn Forte * Kernel context.
1657fcf3ce44SJohn Forte */
1658fcf3ce44SJohn Forte int
ql_logout_fabric_port(ql_adapter_state_t * ha,ql_tgt_t * tq)1659fcf3ce44SJohn Forte ql_logout_fabric_port(ql_adapter_state_t *ha, ql_tgt_t *tq)
1660fcf3ce44SJohn Forte {
1661fcf3ce44SJohn Forte int rval;
16625dfd244aSDaniel Beauregard uint16_t flag;
1663fcf3ce44SJohn Forte ql_mbx_data_t mr;
1664fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1665fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1666fcf3ce44SJohn Forte
1667*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, loop_id=%xh d_id=%xh\n",
1668*4c3888b8SHans Rosenfeld tq->loop_id, tq->d_id.b24);
1669*4c3888b8SHans Rosenfeld
1670*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1671*4c3888b8SHans Rosenfeld if ((ha->topology & QL_N_PORT) &&
1672*4c3888b8SHans Rosenfeld (tq->loop_id != 0x7fe) &&
1673*4c3888b8SHans Rosenfeld (tq->loop_id != 0x7ff)) {
1674*4c3888b8SHans Rosenfeld flag = (uint16_t)(CFO_IMPLICIT_LOGO |
1675*4c3888b8SHans Rosenfeld CF_CMD_LOGO | CFO_FREE_N_PORT_HANDLE);
1676*4c3888b8SHans Rosenfeld
1677*4c3888b8SHans Rosenfeld rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1678*4c3888b8SHans Rosenfeld } else {
1679*4c3888b8SHans Rosenfeld flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ?
1680*4c3888b8SHans Rosenfeld CFO_EXPLICIT_LOGO | CF_CMD_LOGO |
1681*4c3888b8SHans Rosenfeld CFO_FREE_N_PORT_HANDLE :
1682*4c3888b8SHans Rosenfeld CFO_IMPLICIT_LOGO | CF_CMD_LOGO |
1683*4c3888b8SHans Rosenfeld CFO_FREE_N_PORT_HANDLE);
1684*4c3888b8SHans Rosenfeld
1685*4c3888b8SHans Rosenfeld rval = ql_log_iocb(ha, tq, tq->loop_id, flag, &mr);
1686*4c3888b8SHans Rosenfeld }
1687fcf3ce44SJohn Forte
1688*4c3888b8SHans Rosenfeld if (rval == QL_SUCCESS) {
1689*4c3888b8SHans Rosenfeld EL(ha, "tq=%ph, loop_id=%xh, d_id=%xh, flag=%xh\n",
1690*4c3888b8SHans Rosenfeld tq, tq->loop_id, tq->d_id.b24, flag);
1691*4c3888b8SHans Rosenfeld }
1692fcf3ce44SJohn Forte } else {
1693*4c3888b8SHans Rosenfeld flag = (uint16_t)(RESERVED_LOOP_ID(ha, tq->loop_id) ? 1 : 0);
1694fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1695fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1696fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
16975dfd244aSDaniel Beauregard mcp->mb[10] = flag;
1698fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_1|MBX_0;
1699fcf3ce44SJohn Forte } else {
17005dfd244aSDaniel Beauregard mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | flag);
1701fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
1702fcf3ce44SJohn Forte }
1703fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1704fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1705fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1706fcf3ce44SJohn Forte }
1707fcf3ce44SJohn Forte
1708fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1709*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n", rval,
1710fcf3ce44SJohn Forte tq->d_id.b24, tq->loop_id);
1711fcf3ce44SJohn Forte } else {
1712fcf3ce44SJohn Forte /*EMPTY*/
1713*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1714fcf3ce44SJohn Forte }
1715fcf3ce44SJohn Forte
1716fcf3ce44SJohn Forte return (rval);
1717fcf3ce44SJohn Forte }
1718fcf3ce44SJohn Forte
1719fcf3ce44SJohn Forte /*
1720fcf3ce44SJohn Forte * ql_log_iocb
1721fcf3ce44SJohn Forte * Function issues login/logout IOCB.
1722fcf3ce44SJohn Forte *
1723fcf3ce44SJohn Forte * Input:
1724fcf3ce44SJohn Forte * ha: adapter state pointer.
1725fcf3ce44SJohn Forte * tq: target queue pointer.
1726fcf3ce44SJohn Forte * loop_id: FC Loop ID.
1727fcf3ce44SJohn Forte * flags: control flags.
1728fcf3ce44SJohn Forte * mr: pointer for mailbox data.
1729fcf3ce44SJohn Forte *
1730fcf3ce44SJohn Forte * Returns:
1731fcf3ce44SJohn Forte * ql local function return status code.
1732fcf3ce44SJohn Forte *
1733fcf3ce44SJohn Forte * Context:
1734fcf3ce44SJohn Forte * Kernel context.
1735fcf3ce44SJohn Forte */
1736fcf3ce44SJohn Forte int
ql_log_iocb(ql_adapter_state_t * ha,ql_tgt_t * tq,uint16_t loop_id,uint16_t flags,ql_mbx_data_t * mr)1737fcf3ce44SJohn Forte ql_log_iocb(ql_adapter_state_t *ha, ql_tgt_t *tq, uint16_t loop_id,
1738fcf3ce44SJohn Forte uint16_t flags, ql_mbx_data_t *mr)
1739fcf3ce44SJohn Forte {
1740fcf3ce44SJohn Forte ql_mbx_iocb_t *pkt;
1741fcf3ce44SJohn Forte int rval;
1742fcf3ce44SJohn Forte uint32_t pkt_size;
1743fcf3ce44SJohn Forte
1744*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1745fcf3ce44SJohn Forte
1746fcf3ce44SJohn Forte pkt_size = sizeof (ql_mbx_iocb_t);
1747fcf3ce44SJohn Forte pkt = kmem_zalloc(pkt_size, KM_SLEEP);
1748fcf3ce44SJohn Forte if (pkt == NULL) {
1749fcf3ce44SJohn Forte EL(ha, "failed, kmem_zalloc\n");
1750fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
1751fcf3ce44SJohn Forte }
1752fcf3ce44SJohn Forte
1753fcf3ce44SJohn Forte pkt->log.entry_type = LOG_TYPE;
1754fcf3ce44SJohn Forte pkt->log.entry_count = 1;
1755fcf3ce44SJohn Forte pkt->log.n_port_hdl = (uint16_t)LE_16(loop_id);
1756fcf3ce44SJohn Forte pkt->log.control_flags = (uint16_t)LE_16(flags);
1757fcf3ce44SJohn Forte pkt->log.port_id[0] = tq->d_id.b.al_pa;
1758fcf3ce44SJohn Forte pkt->log.port_id[1] = tq->d_id.b.area;
1759fcf3ce44SJohn Forte pkt->log.port_id[2] = tq->d_id.b.domain;
1760fcf3ce44SJohn Forte pkt->log.vp_index = ha->vp_index;
1761fcf3ce44SJohn Forte
1762fcf3ce44SJohn Forte rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
1763fcf3ce44SJohn Forte if (rval == QL_SUCCESS && (pkt->log.entry_status & 0x3c) != 0) {
1764fcf3ce44SJohn Forte EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
1765fcf3ce44SJohn Forte pkt->log.entry_status, tq->d_id.b24);
1766fcf3ce44SJohn Forte rval = QL_FUNCTION_PARAMETER_ERROR;
1767fcf3ce44SJohn Forte }
1768fcf3ce44SJohn Forte
1769fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
1770fcf3ce44SJohn Forte if (pkt->log.rsp_size == 0xB) {
1771fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[5]);
1772fcf3ce44SJohn Forte tq->cmn_features = MSW(pkt->log.io_param[5]);
1773fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[6]);
1774fcf3ce44SJohn Forte tq->conc_sequences = MSW(pkt->log.io_param[6]);
1775fcf3ce44SJohn Forte tq->relative_offset = LSW(pkt->log.io_param[6]);
1776fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[9]);
1777fcf3ce44SJohn Forte tq->class3_recipient_ctl = MSW(pkt->log.io_param[9]);
1778fcf3ce44SJohn Forte tq->class3_conc_sequences = LSW(pkt->log.io_param[9]);
1779fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[10]);
1780fcf3ce44SJohn Forte tq->class3_open_sequences_per_exch =
1781fcf3ce44SJohn Forte MSW(pkt->log.io_param[10]);
1782fcf3ce44SJohn Forte tq->prli_payload_length = 0x14;
1783fcf3ce44SJohn Forte }
1784fcf3ce44SJohn Forte if (mr != NULL) {
1785fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&pkt->log.status);
1786fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[0]);
1787fcf3ce44SJohn Forte LITTLE_ENDIAN_32(&pkt->log.io_param[1]);
1788fcf3ce44SJohn Forte
1789fcf3ce44SJohn Forte if (pkt->log.status != CS_COMPLETE) {
1790fcf3ce44SJohn Forte EL(ha, "failed, status=%xh, iop0=%xh, iop1="
1791fcf3ce44SJohn Forte "%xh\n", pkt->log.status,
1792fcf3ce44SJohn Forte pkt->log.io_param[0],
1793fcf3ce44SJohn Forte pkt->log.io_param[1]);
1794fcf3ce44SJohn Forte
1795fcf3ce44SJohn Forte switch (pkt->log.io_param[0]) {
1796fcf3ce44SJohn Forte case CS0_NO_LINK:
1797fcf3ce44SJohn Forte case CS0_FIRMWARE_NOT_READY:
1798fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1799fcf3ce44SJohn Forte mr->mb[1] = 1;
1800fcf3ce44SJohn Forte break;
1801fcf3ce44SJohn Forte case CS0_NO_IOCB:
1802fcf3ce44SJohn Forte case CS0_NO_PCB_ALLOCATED:
1803fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1804fcf3ce44SJohn Forte mr->mb[1] = 2;
1805fcf3ce44SJohn Forte break;
1806fcf3ce44SJohn Forte case CS0_NO_EXCH_CTRL_BLK:
1807fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1808fcf3ce44SJohn Forte mr->mb[1] = 3;
1809fcf3ce44SJohn Forte break;
1810fcf3ce44SJohn Forte case CS0_COMMAND_FAILED:
1811fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1812fcf3ce44SJohn Forte mr->mb[1] = 4;
1813fcf3ce44SJohn Forte switch (LSB(pkt->log.io_param[1])) {
1814fcf3ce44SJohn Forte case CS1_PLOGI_RESPONSE_FAILED:
1815fcf3ce44SJohn Forte mr->mb[2] = 3;
1816fcf3ce44SJohn Forte break;
1817fcf3ce44SJohn Forte case CS1_PRLI_FAILED:
1818fcf3ce44SJohn Forte mr->mb[2] = 4;
1819fcf3ce44SJohn Forte break;
1820fcf3ce44SJohn Forte case CS1_PRLI_RESPONSE_FAILED:
1821fcf3ce44SJohn Forte mr->mb[2] = 5;
1822fcf3ce44SJohn Forte break;
1823fcf3ce44SJohn Forte case CS1_COMMAND_LOGGED_OUT:
1824fcf3ce44SJohn Forte mr->mb[2] = 7;
1825fcf3ce44SJohn Forte break;
1826fcf3ce44SJohn Forte case CS1_PLOGI_FAILED:
1827fcf3ce44SJohn Forte default:
1828fcf3ce44SJohn Forte EL(ha, "log iop1 = %xh\n",
1829fcf3ce44SJohn Forte LSB(pkt->log.io_param[1]))
1830fcf3ce44SJohn Forte mr->mb[2] = 2;
1831fcf3ce44SJohn Forte break;
1832fcf3ce44SJohn Forte }
1833fcf3ce44SJohn Forte break;
1834fcf3ce44SJohn Forte case CS0_PORT_NOT_LOGGED_IN:
1835fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1836fcf3ce44SJohn Forte mr->mb[1] = 4;
1837fcf3ce44SJohn Forte mr->mb[2] = 7;
1838fcf3ce44SJohn Forte break;
1839fcf3ce44SJohn Forte case CS0_NO_FLOGI_ACC:
1840fcf3ce44SJohn Forte case CS0_NO_FABRIC_PRESENT:
1841fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1842fcf3ce44SJohn Forte mr->mb[1] = 5;
1843fcf3ce44SJohn Forte break;
1844fcf3ce44SJohn Forte case CS0_ELS_REJECT_RECEIVED:
1845fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_ERROR;
1846fcf3ce44SJohn Forte mr->mb[1] = 0xd;
1847fcf3ce44SJohn Forte break;
1848fcf3ce44SJohn Forte case CS0_PORT_ID_USED:
1849fcf3ce44SJohn Forte mr->mb[0] = MBS_PORT_ID_USED;
1850fcf3ce44SJohn Forte mr->mb[1] = LSW(pkt->log.io_param[1]);
1851fcf3ce44SJohn Forte break;
1852fcf3ce44SJohn Forte case CS0_N_PORT_HANDLE_USED:
1853fcf3ce44SJohn Forte mr->mb[0] = MBS_LOOP_ID_USED;
1854fcf3ce44SJohn Forte mr->mb[1] = MSW(pkt->log.io_param[1]);
1855fcf3ce44SJohn Forte mr->mb[2] = LSW(pkt->log.io_param[1]);
1856fcf3ce44SJohn Forte break;
1857fcf3ce44SJohn Forte case CS0_NO_N_PORT_HANDLE_AVAILABLE:
1858fcf3ce44SJohn Forte mr->mb[0] = MBS_ALL_IDS_IN_USE;
1859fcf3ce44SJohn Forte break;
1860fcf3ce44SJohn Forte case CS0_CMD_PARAMETER_ERROR:
1861fcf3ce44SJohn Forte default:
1862fcf3ce44SJohn Forte EL(ha, "pkt->log iop[0]=%xh\n",
1863fcf3ce44SJohn Forte pkt->log.io_param[0]);
1864fcf3ce44SJohn Forte mr->mb[0] =
1865fcf3ce44SJohn Forte MBS_COMMAND_PARAMETER_ERROR;
1866fcf3ce44SJohn Forte break;
1867fcf3ce44SJohn Forte }
1868fcf3ce44SJohn Forte } else {
1869*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "status=%xh\n", pkt->log.status);
1870fcf3ce44SJohn Forte
1871fcf3ce44SJohn Forte mr->mb[0] = MBS_COMMAND_COMPLETE;
1872fcf3ce44SJohn Forte mr->mb[1] = (uint16_t)
1873fcf3ce44SJohn Forte (pkt->log.io_param[0] & BIT_4 ? 0 : BIT_0);
1874fcf3ce44SJohn Forte if (pkt->log.io_param[0] & BIT_8) {
1875fcf3ce44SJohn Forte mr->mb[1] = (uint16_t)
1876fcf3ce44SJohn Forte (mr->mb[1] | BIT_1);
1877fcf3ce44SJohn Forte }
1878fcf3ce44SJohn Forte }
1879fcf3ce44SJohn Forte rval = mr->mb[0];
1880fcf3ce44SJohn Forte }
1881fcf3ce44SJohn Forte
1882fcf3ce44SJohn Forte }
1883fcf3ce44SJohn Forte
1884fcf3ce44SJohn Forte kmem_free(pkt, pkt_size);
1885fcf3ce44SJohn Forte
1886fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
1887*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, d_id=%xh loop_id=%xh\n",
1888*4c3888b8SHans Rosenfeld rval, tq->d_id.b24, loop_id);
1889fcf3ce44SJohn Forte } else {
1890fcf3ce44SJohn Forte /*EMPTY*/
1891*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
1892fcf3ce44SJohn Forte }
1893fcf3ce44SJohn Forte
1894fcf3ce44SJohn Forte return (rval);
1895fcf3ce44SJohn Forte }
1896fcf3ce44SJohn Forte
1897fcf3ce44SJohn Forte /*
1898fcf3ce44SJohn Forte * ql_get_port_database
1899fcf3ce44SJohn Forte * Issue get port database mailbox command
1900fcf3ce44SJohn Forte * and copy context to device queue.
1901fcf3ce44SJohn Forte *
1902fcf3ce44SJohn Forte * Input:
1903fcf3ce44SJohn Forte * ha: adapter state pointer.
1904fcf3ce44SJohn Forte * tq: target queue pointer.
1905fcf3ce44SJohn Forte * opt: options.
1906fcf3ce44SJohn Forte * PDF_NONE, PDF_PLOGI, PDF_ADISC
1907fcf3ce44SJohn Forte * Returns:
1908fcf3ce44SJohn Forte * ql local function return status code.
1909fcf3ce44SJohn Forte *
1910fcf3ce44SJohn Forte * Context:
1911fcf3ce44SJohn Forte * Kernel context.
1912fcf3ce44SJohn Forte */
1913fcf3ce44SJohn Forte int
ql_get_port_database(ql_adapter_state_t * ha,ql_tgt_t * tq,uint8_t opt)1914fcf3ce44SJohn Forte ql_get_port_database(ql_adapter_state_t *ha, ql_tgt_t *tq, uint8_t opt)
1915fcf3ce44SJohn Forte {
1916fcf3ce44SJohn Forte int rval;
1917fcf3ce44SJohn Forte dma_mem_t mem_desc;
1918fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
1919fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
1920fcf3ce44SJohn Forte port_database_23_t *pd23;
1921fcf3ce44SJohn Forte
1922*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
1923fcf3ce44SJohn Forte
1924fcf3ce44SJohn Forte pd23 = (port_database_23_t *)kmem_zalloc(PORT_DATABASE_SIZE, KM_SLEEP);
1925fcf3ce44SJohn Forte if (pd23 == NULL) {
1926fcf3ce44SJohn Forte rval = QL_MEMORY_ALLOC_FAILED;
1927fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
1928fcf3ce44SJohn Forte return (rval);
1929fcf3ce44SJohn Forte }
1930fcf3ce44SJohn Forte
1931fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
1932fcf3ce44SJohn Forte PORT_DATABASE_SIZE)) != QL_SUCCESS) {
1933fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
1934fcf3ce44SJohn Forte }
1935fcf3ce44SJohn Forte
1936*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1937fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_PORT_DATABASE;
1938fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1939fcf3ce44SJohn Forte mcp->mb[4] = CHAR_TO_SHORT(tq->d_id.b.al_pa, tq->d_id.b.area);
1940fcf3ce44SJohn Forte mcp->mb[5] = (uint16_t)tq->d_id.b.domain;
1941fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
1942fcf3ce44SJohn Forte mcp->mb[10] = (uint16_t)(opt | PDF_ADISC);
1943fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
1944fcf3ce44SJohn Forte MBX_2|MBX_1|MBX_0;
1945fcf3ce44SJohn Forte } else {
1946fcf3ce44SJohn Forte mcp->mb[0] = (uint16_t)(opt == PDF_NONE ?
1947fcf3ce44SJohn Forte MBC_GET_PORT_DATABASE : MBC_ENHANCED_GET_PORT_DATABASE);
1948fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
1949fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
1950fcf3ce44SJohn Forte mcp->mb[10] = opt;
1951fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|
1952fcf3ce44SJohn Forte MBX_2|MBX_1|MBX_0;
1953fcf3ce44SJohn Forte } else {
1954fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8 | opt);
1955fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1956fcf3ce44SJohn Forte }
1957fcf3ce44SJohn Forte }
1958fcf3ce44SJohn Forte
1959fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
1960fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
1961fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
1962fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
1963fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
1964fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
1965fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
1966fcf3ce44SJohn Forte
1967fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
1968fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, (caddr_t)pd23);
1969fcf3ce44SJohn Forte }
1970fcf3ce44SJohn Forte
1971fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
1972fcf3ce44SJohn Forte
1973fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
1974*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
1975fcf3ce44SJohn Forte port_database_24_t *pd24 = (port_database_24_t *)pd23;
1976fcf3ce44SJohn Forte
1977fcf3ce44SJohn Forte tq->master_state = pd24->current_login_state;
1978fcf3ce44SJohn Forte tq->slave_state = pd24->last_stable_login_state;
1979fcf3ce44SJohn Forte if (PD_PORT_LOGIN(tq)) {
1980fcf3ce44SJohn Forte /* Names are big endian. */
1981fcf3ce44SJohn Forte bcopy((void *)&pd24->port_name[0],
1982fcf3ce44SJohn Forte (void *)&tq->port_name[0], 8);
1983fcf3ce44SJohn Forte bcopy((void *)&pd24->node_name[0],
1984fcf3ce44SJohn Forte (void *)&tq->node_name[0], 8);
1985fcf3ce44SJohn Forte tq->hard_addr.b.al_pa = pd24->hard_address[2];
1986fcf3ce44SJohn Forte tq->hard_addr.b.area = pd24->hard_address[1];
1987fcf3ce44SJohn Forte tq->hard_addr.b.domain = pd24->hard_address[0];
1988fcf3ce44SJohn Forte tq->class3_rcv_data_size =
1989fcf3ce44SJohn Forte pd24->receive_data_size;
1990fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
1991fcf3ce44SJohn Forte tq->prli_svc_param_word_0 =
1992fcf3ce44SJohn Forte pd24->PRLI_service_parameter_word_0;
1993fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
1994fcf3ce44SJohn Forte tq->prli_svc_param_word_3 =
1995fcf3ce44SJohn Forte pd24->PRLI_service_parameter_word_3;
1996fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
1997fcf3ce44SJohn Forte }
1998fcf3ce44SJohn Forte } else {
1999fcf3ce44SJohn Forte tq->master_state = pd23->master_state;
2000fcf3ce44SJohn Forte tq->slave_state = pd23->slave_state;
2001fcf3ce44SJohn Forte if (PD_PORT_LOGIN(tq)) {
2002fcf3ce44SJohn Forte /* Names are big endian. */
2003fcf3ce44SJohn Forte bcopy((void *)&pd23->port_name[0],
2004fcf3ce44SJohn Forte (void *)&tq->port_name[0], 8);
2005fcf3ce44SJohn Forte bcopy((void *)&pd23->node_name[0],
2006fcf3ce44SJohn Forte (void *)&tq->node_name[0], 8);
2007fcf3ce44SJohn Forte tq->hard_addr.b.al_pa = pd23->hard_address[2];
2008fcf3ce44SJohn Forte tq->hard_addr.b.area = pd23->hard_address[1];
2009fcf3ce44SJohn Forte tq->hard_addr.b.domain = pd23->hard_address[0];
2010fcf3ce44SJohn Forte tq->cmn_features = pd23->common_features;
2011fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->cmn_features);
2012fcf3ce44SJohn Forte tq->conc_sequences =
2013fcf3ce44SJohn Forte pd23->total_concurrent_sequences;
2014fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->conc_sequences);
2015fcf3ce44SJohn Forte tq->relative_offset =
2016fcf3ce44SJohn Forte pd23->RO_by_information_category;
2017fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->relative_offset);
2018fcf3ce44SJohn Forte tq->class3_recipient_ctl = pd23->recipient;
2019fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->class3_recipient_ctl);
2020fcf3ce44SJohn Forte tq->class3_rcv_data_size =
2021fcf3ce44SJohn Forte pd23->receive_data_size;
2022fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->class3_rcv_data_size);
2023fcf3ce44SJohn Forte tq->class3_conc_sequences =
2024fcf3ce44SJohn Forte pd23->concurrent_sequences;
2025fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->class3_conc_sequences);
2026fcf3ce44SJohn Forte tq->class3_open_sequences_per_exch =
2027fcf3ce44SJohn Forte pd23->open_sequences_per_exchange;
2028fcf3ce44SJohn Forte LITTLE_ENDIAN_16(
2029fcf3ce44SJohn Forte &tq->class3_open_sequences_per_exch);
2030fcf3ce44SJohn Forte tq->prli_payload_length =
2031fcf3ce44SJohn Forte pd23->PRLI_payload_length;
2032fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->prli_payload_length);
2033fcf3ce44SJohn Forte tq->prli_svc_param_word_0 =
2034fcf3ce44SJohn Forte pd23->PRLI_service_parameter_word_0;
2035fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->prli_svc_param_word_0);
2036fcf3ce44SJohn Forte tq->prli_svc_param_word_3 =
2037fcf3ce44SJohn Forte pd23->PRLI_service_parameter_word_3;
2038fcf3ce44SJohn Forte LITTLE_ENDIAN_16(&tq->prli_svc_param_word_3);
2039fcf3ce44SJohn Forte }
2040fcf3ce44SJohn Forte }
2041fcf3ce44SJohn Forte
2042fcf3ce44SJohn Forte if (!PD_PORT_LOGIN(tq)) {
2043fcf3ce44SJohn Forte EL(ha, "d_id=%xh, loop_id=%xh, not logged in "
2044fcf3ce44SJohn Forte "master=%xh, slave=%xh\n", tq->d_id.b24,
2045fcf3ce44SJohn Forte tq->loop_id, tq->master_state, tq->slave_state);
204616dd44c2SDaniel Beauregard rval = QL_NOT_LOGGED_IN;
2047fcf3ce44SJohn Forte } else {
204816dd44c2SDaniel Beauregard tq->flags = tq->prli_svc_param_word_3 &
204916dd44c2SDaniel Beauregard PRLI_W3_TARGET_FUNCTION ?
2050fcf3ce44SJohn Forte tq->flags & ~TQF_INITIATOR_DEVICE :
2051fcf3ce44SJohn Forte tq->flags | TQF_INITIATOR_DEVICE;
2052fcf3ce44SJohn Forte
2053fcf3ce44SJohn Forte if ((tq->flags & TQF_INITIATOR_DEVICE) == 0) {
205416dd44c2SDaniel Beauregard tq->flags = tq->prli_svc_param_word_3 &
205516dd44c2SDaniel Beauregard PRLI_W3_RETRY ?
2056fcf3ce44SJohn Forte tq->flags | TQF_TAPE_DEVICE :
2057fcf3ce44SJohn Forte tq->flags & ~TQF_TAPE_DEVICE;
2058fcf3ce44SJohn Forte } else {
2059fcf3ce44SJohn Forte tq->flags &= ~TQF_TAPE_DEVICE;
2060fcf3ce44SJohn Forte }
2061fcf3ce44SJohn Forte }
2062fcf3ce44SJohn Forte }
2063fcf3ce44SJohn Forte
2064fcf3ce44SJohn Forte kmem_free(pd23, PORT_DATABASE_SIZE);
2065fcf3ce44SJohn Forte
2066*4c3888b8SHans Rosenfeld /*
2067*4c3888b8SHans Rosenfeld * log the trace in any cases other than QL_SUCCESS.
2068*4c3888b8SHans Rosenfeld */
2069*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
2070*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, d_id=%xh, loop_id=%xh\n",
2071*4c3888b8SHans Rosenfeld rval, tq->d_id.b24, tq->loop_id);
2072fcf3ce44SJohn Forte } else {
2073fcf3ce44SJohn Forte /*EMPTY*/
2074*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2075fcf3ce44SJohn Forte }
2076fcf3ce44SJohn Forte
2077fcf3ce44SJohn Forte return (rval);
2078fcf3ce44SJohn Forte }
2079fcf3ce44SJohn Forte
2080fcf3ce44SJohn Forte /*
2081fcf3ce44SJohn Forte * ql_get_loop_position_map
2082fcf3ce44SJohn Forte * Issue get loop position map mailbox command.
2083fcf3ce44SJohn Forte *
2084fcf3ce44SJohn Forte * Input:
2085fcf3ce44SJohn Forte * ha: adapter state pointer.
2086fcf3ce44SJohn Forte * size: size of data buffer.
2087fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2088fcf3ce44SJohn Forte *
2089fcf3ce44SJohn Forte * Returns:
2090fcf3ce44SJohn Forte * ql local function return status code.
2091fcf3ce44SJohn Forte *
2092fcf3ce44SJohn Forte * Context:
2093fcf3ce44SJohn Forte * Kernel context.
2094fcf3ce44SJohn Forte */
2095fcf3ce44SJohn Forte int
ql_get_loop_position_map(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2096fcf3ce44SJohn Forte ql_get_loop_position_map(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2097fcf3ce44SJohn Forte {
2098fcf3ce44SJohn Forte int rval;
2099fcf3ce44SJohn Forte dma_mem_t mem_desc;
2100fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2101fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2102fcf3ce44SJohn Forte
2103*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2104fcf3ce44SJohn Forte
2105fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2106fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2107fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2108fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2109fcf3ce44SJohn Forte }
2110fcf3ce44SJohn Forte
2111fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2112fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2113fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2114fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2115fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2116fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2117fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
2118fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2119fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2120fcf3ce44SJohn Forte
2121fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2122fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bufp);
2123fcf3ce44SJohn Forte }
2124fcf3ce44SJohn Forte
2125fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2126fcf3ce44SJohn Forte
2127fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2128fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
2129fcf3ce44SJohn Forte } else {
2130fcf3ce44SJohn Forte /*EMPTY*/
2131*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2132fcf3ce44SJohn Forte }
2133fcf3ce44SJohn Forte
2134fcf3ce44SJohn Forte return (rval);
2135fcf3ce44SJohn Forte }
2136fcf3ce44SJohn Forte
2137fcf3ce44SJohn Forte /*
2138fcf3ce44SJohn Forte * ql_set_rnid_params
2139fcf3ce44SJohn Forte * Issue set RNID parameters mailbox command.
2140fcf3ce44SJohn Forte *
2141fcf3ce44SJohn Forte * Input:
2142fcf3ce44SJohn Forte * ha: adapter state pointer.
2143fcf3ce44SJohn Forte * size: size of data buffer.
2144fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2145fcf3ce44SJohn Forte *
2146fcf3ce44SJohn Forte * Returns:
2147fcf3ce44SJohn Forte * ql local function return status code.
2148fcf3ce44SJohn Forte *
2149fcf3ce44SJohn Forte * Context:
2150fcf3ce44SJohn Forte * Kernel context.
2151fcf3ce44SJohn Forte */
2152fcf3ce44SJohn Forte int
ql_set_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2153fcf3ce44SJohn Forte ql_set_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2154fcf3ce44SJohn Forte {
2155fcf3ce44SJohn Forte int rval;
2156fcf3ce44SJohn Forte dma_mem_t mem_desc;
2157fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2158fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2159fcf3ce44SJohn Forte
2160*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2161fcf3ce44SJohn Forte
2162fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bufp,
2163fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2164fcf3ce44SJohn Forte EL(ha, "failed, setup_mbox_dma_transfer: %x\n", rval);
2165fcf3ce44SJohn Forte return (rval);
2166fcf3ce44SJohn Forte }
2167fcf3ce44SJohn Forte
2168fcf3ce44SJohn Forte mcp->mb[0] = MBC_SET_PARAMETERS;
2169fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2170fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2171fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2172fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2173fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2174fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2175fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2176fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2177fcf3ce44SJohn Forte
2178fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2179fcf3ce44SJohn Forte
2180fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2181fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2182fcf3ce44SJohn Forte } else {
2183fcf3ce44SJohn Forte /*EMPTY*/
2184*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2185fcf3ce44SJohn Forte }
2186fcf3ce44SJohn Forte
2187fcf3ce44SJohn Forte return (rval);
2188fcf3ce44SJohn Forte }
2189fcf3ce44SJohn Forte
2190fcf3ce44SJohn Forte /*
2191fcf3ce44SJohn Forte * ql_send_rnid_els
2192fcf3ce44SJohn Forte * Issue a send node identfication data mailbox command.
2193fcf3ce44SJohn Forte *
2194fcf3ce44SJohn Forte * Input:
2195fcf3ce44SJohn Forte * ha: adapter state pointer.
2196fcf3ce44SJohn Forte * loop_id: FC loop id.
2197fcf3ce44SJohn Forte * opt: options.
2198fcf3ce44SJohn Forte * size: size of data buffer.
2199fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2200fcf3ce44SJohn Forte *
2201fcf3ce44SJohn Forte * Returns:
2202fcf3ce44SJohn Forte * ql local function return status code.
2203fcf3ce44SJohn Forte *
2204fcf3ce44SJohn Forte * Context:
2205fcf3ce44SJohn Forte * Kernel context.
2206fcf3ce44SJohn Forte */
2207fcf3ce44SJohn Forte int
ql_send_rnid_els(ql_adapter_state_t * ha,uint16_t loop_id,uint8_t opt,size_t size,caddr_t bufp)2208fcf3ce44SJohn Forte ql_send_rnid_els(ql_adapter_state_t *ha, uint16_t loop_id, uint8_t opt,
2209fcf3ce44SJohn Forte size_t size, caddr_t bufp)
2210fcf3ce44SJohn Forte {
2211fcf3ce44SJohn Forte int rval;
2212fcf3ce44SJohn Forte dma_mem_t mem_desc;
2213fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2214fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2215fcf3ce44SJohn Forte
2216*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2217fcf3ce44SJohn Forte
2218fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2219fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2220fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2221fcf3ce44SJohn Forte }
2222fcf3ce44SJohn Forte
2223fcf3ce44SJohn Forte mcp->mb[0] = MBC_SEND_RNID_ELS;
2224*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2225fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2226fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
2227fcf3ce44SJohn Forte mcp->mb[10] = opt;
2228fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2229fcf3ce44SJohn Forte } else if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2230fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2231fcf3ce44SJohn Forte mcp->mb[10] = opt;
2232fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2233fcf3ce44SJohn Forte } else {
2234fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(loop_id << 8 | opt);
2235fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2236fcf3ce44SJohn Forte }
2237fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2238fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2239fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2240fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2241fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2242fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2243fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2244fcf3ce44SJohn Forte
2245fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2246fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bufp);
2247fcf3ce44SJohn Forte }
2248fcf3ce44SJohn Forte
2249fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2250fcf3ce44SJohn Forte
2251fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2252fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2253fcf3ce44SJohn Forte } else {
2254fcf3ce44SJohn Forte /*EMPTY*/
2255*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2256fcf3ce44SJohn Forte }
2257fcf3ce44SJohn Forte
2258fcf3ce44SJohn Forte return (rval);
2259fcf3ce44SJohn Forte }
2260fcf3ce44SJohn Forte
2261fcf3ce44SJohn Forte /*
2262fcf3ce44SJohn Forte * ql_get_rnid_params
2263fcf3ce44SJohn Forte * Issue get RNID parameters mailbox command.
2264fcf3ce44SJohn Forte *
2265fcf3ce44SJohn Forte * Input:
2266fcf3ce44SJohn Forte * ha: adapter state pointer.
2267fcf3ce44SJohn Forte * size: size of data buffer.
2268fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2269fcf3ce44SJohn Forte *
2270fcf3ce44SJohn Forte * Returns:
2271fcf3ce44SJohn Forte * ql local function return status code.
2272fcf3ce44SJohn Forte *
2273fcf3ce44SJohn Forte * Context:
2274fcf3ce44SJohn Forte * Kernel context.
2275fcf3ce44SJohn Forte */
2276fcf3ce44SJohn Forte int
ql_get_rnid_params(ql_adapter_state_t * ha,size_t size,caddr_t bufp)2277fcf3ce44SJohn Forte ql_get_rnid_params(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
2278fcf3ce44SJohn Forte {
2279fcf3ce44SJohn Forte int rval;
2280fcf3ce44SJohn Forte dma_mem_t mem_desc;
2281fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2282fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2283fcf3ce44SJohn Forte
2284*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2285fcf3ce44SJohn Forte
2286fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2287fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2288fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2289fcf3ce44SJohn Forte }
2290fcf3ce44SJohn Forte
2291fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_PARAMETERS;
2292fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2293fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2294fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2295fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2296fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2297fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2298fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2299fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2300fcf3ce44SJohn Forte
2301fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2302fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bufp);
2303fcf3ce44SJohn Forte }
2304fcf3ce44SJohn Forte
2305fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2306fcf3ce44SJohn Forte
2307fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2308fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
2309fcf3ce44SJohn Forte } else {
2310fcf3ce44SJohn Forte /*EMPTY*/
2311*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2312fcf3ce44SJohn Forte }
2313fcf3ce44SJohn Forte
2314fcf3ce44SJohn Forte return (rval);
2315fcf3ce44SJohn Forte }
2316fcf3ce44SJohn Forte
2317fcf3ce44SJohn Forte /*
2318fcf3ce44SJohn Forte * ql_get_link_status
2319fcf3ce44SJohn Forte * Issue get link status mailbox command.
2320fcf3ce44SJohn Forte *
2321fcf3ce44SJohn Forte * Input:
2322fcf3ce44SJohn Forte * ha: adapter state pointer.
2323fcf3ce44SJohn Forte * loop_id: FC loop id or n_port_hdl.
2324fcf3ce44SJohn Forte * size: size of data buffer.
2325fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2326fcf3ce44SJohn Forte * port_no: port number to query.
2327fcf3ce44SJohn Forte *
2328fcf3ce44SJohn Forte * Returns:
2329fcf3ce44SJohn Forte * ql local function return status code.
2330fcf3ce44SJohn Forte *
2331fcf3ce44SJohn Forte * Context:
2332fcf3ce44SJohn Forte * Kernel context.
2333fcf3ce44SJohn Forte */
2334fcf3ce44SJohn Forte int
ql_get_link_status(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2335fcf3ce44SJohn Forte ql_get_link_status(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2336fcf3ce44SJohn Forte caddr_t bufp, uint8_t port_no)
2337fcf3ce44SJohn Forte {
2338fcf3ce44SJohn Forte dma_mem_t mem_desc;
2339fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2340fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2341fcf3ce44SJohn Forte int rval = QL_SUCCESS;
2342fcf3ce44SJohn Forte int retry = 0;
2343fcf3ce44SJohn Forte
2344*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2345fcf3ce44SJohn Forte
2346fcf3ce44SJohn Forte do {
2347fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2348fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2349fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2350fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2351fcf3ce44SJohn Forte }
2352fcf3ce44SJohn Forte
2353fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_LINK_STATUS;
2354*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2355fcf3ce44SJohn Forte if (loop_id == ha->loop_id) {
2356fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2357fcf3ce44SJohn Forte mcp->mb[8] = (uint16_t)(size >> 2);
2358fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_8;
2359fcf3ce44SJohn Forte } else {
2360fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2361fcf3ce44SJohn Forte mcp->mb[4] = port_no;
2362fcf3ce44SJohn Forte mcp->mb[10] = (uint16_t)(retry ? BIT_3 : 0);
2363fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_4;
2364fcf3ce44SJohn Forte }
2365fcf3ce44SJohn Forte } else {
2366fcf3ce44SJohn Forte if (retry) {
2367fcf3ce44SJohn Forte port_no = (uint8_t)(port_no | BIT_3);
2368fcf3ce44SJohn Forte }
2369fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2370fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2371fcf3ce44SJohn Forte mcp->mb[10] = port_no;
2372fcf3ce44SJohn Forte mcp->out_mb = MBX_10;
2373fcf3ce44SJohn Forte } else {
2374fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)((loop_id << 8) |
2375fcf3ce44SJohn Forte port_no);
2376fcf3ce44SJohn Forte mcp->out_mb = 0;
2377fcf3ce44SJohn Forte }
2378fcf3ce44SJohn Forte }
2379fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2380fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2381fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2382fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2383fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
2384fcf3ce44SJohn Forte mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2385fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2386fcf3ce44SJohn Forte
2387fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2388fcf3ce44SJohn Forte
2389fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2390fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bufp);
2391fcf3ce44SJohn Forte }
2392fcf3ce44SJohn Forte
2393fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2394fcf3ce44SJohn Forte
2395fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2396fcf3ce44SJohn Forte EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2397fcf3ce44SJohn Forte }
2398fcf3ce44SJohn Forte
2399fcf3ce44SJohn Forte /*
2400fcf3ce44SJohn Forte * Some of the devices want d_id in the payload,
2401fcf3ce44SJohn Forte * strictly as per standard. Let's retry.
2402fcf3ce44SJohn Forte */
2403fcf3ce44SJohn Forte
2404fcf3ce44SJohn Forte } while (rval == QL_COMMAND_ERROR && !retry++);
2405fcf3ce44SJohn Forte
2406fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2407fcf3ce44SJohn Forte EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
2408fcf3ce44SJohn Forte } else {
2409fcf3ce44SJohn Forte /*EMPTY*/
2410*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2411fcf3ce44SJohn Forte }
2412fcf3ce44SJohn Forte
2413fcf3ce44SJohn Forte return (rval);
2414fcf3ce44SJohn Forte }
2415fcf3ce44SJohn Forte
2416fcf3ce44SJohn Forte /*
2417fcf3ce44SJohn Forte * ql_get_status_counts
2418fcf3ce44SJohn Forte * Issue get adapter link status counts mailbox command.
2419fcf3ce44SJohn Forte *
2420fcf3ce44SJohn Forte * Input:
2421fcf3ce44SJohn Forte * ha: adapter state pointer.
2422fcf3ce44SJohn Forte * loop_id: FC loop id or n_port_hdl.
2423fcf3ce44SJohn Forte * size: size of data buffer.
2424fcf3ce44SJohn Forte * bufp: data pointer for DMA data.
2425fcf3ce44SJohn Forte * port_no: port number to query.
2426fcf3ce44SJohn Forte *
2427fcf3ce44SJohn Forte * Returns:
2428fcf3ce44SJohn Forte * ql local function return status code.
2429fcf3ce44SJohn Forte *
2430fcf3ce44SJohn Forte * Context:
2431fcf3ce44SJohn Forte * Kernel context.
2432fcf3ce44SJohn Forte */
2433fcf3ce44SJohn Forte int
ql_get_status_counts(ql_adapter_state_t * ha,uint16_t loop_id,size_t size,caddr_t bufp,uint8_t port_no)2434fcf3ce44SJohn Forte ql_get_status_counts(ql_adapter_state_t *ha, uint16_t loop_id, size_t size,
2435fcf3ce44SJohn Forte caddr_t bufp, uint8_t port_no)
2436fcf3ce44SJohn Forte {
2437fcf3ce44SJohn Forte dma_mem_t mem_desc;
2438fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2439fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2440fcf3ce44SJohn Forte int rval = QL_SUCCESS;
2441fcf3ce44SJohn Forte
2442*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2443fcf3ce44SJohn Forte
2444fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2445fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2446fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_resources failed: %x\n", rval);
2447fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2448fcf3ce44SJohn Forte }
2449fcf3ce44SJohn Forte
2450*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2451fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_STATUS_COUNTS;
2452fcf3ce44SJohn Forte mcp->mb[8] = (uint16_t)(size / 4);
2453fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_8;
2454fcf3ce44SJohn Forte } else {
2455fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_LINK_STATUS;
2456fcf3ce44SJohn Forte
2457fcf3ce44SJohn Forte /* allows reporting when link is down */
2458*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_22XX) == 0) {
2459fcf3ce44SJohn Forte port_no = (uint8_t)(port_no | BIT_6);
2460fcf3ce44SJohn Forte }
2461fcf3ce44SJohn Forte
2462fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2463fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2464fcf3ce44SJohn Forte mcp->mb[10] = port_no;
2465fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_1;
2466fcf3ce44SJohn Forte } else {
2467fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)((loop_id << 8) |
2468fcf3ce44SJohn Forte port_no);
2469fcf3ce44SJohn Forte mcp->out_mb = MBX_1;
2470fcf3ce44SJohn Forte }
2471fcf3ce44SJohn Forte }
2472fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2473fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2474fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2475fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2476fcf3ce44SJohn Forte mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2477fcf3ce44SJohn Forte mcp->in_mb = MBX_2|MBX_1|MBX_0;
2478fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2479fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2480fcf3ce44SJohn Forte
2481fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2482fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bufp);
2483fcf3ce44SJohn Forte }
2484fcf3ce44SJohn Forte
2485fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2486fcf3ce44SJohn Forte
2487fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2488fcf3ce44SJohn Forte EL(ha, "failed=%xh, mbx1=%xh, mbx2=%xh\n", rval,
2489fcf3ce44SJohn Forte mcp->mb[1], mcp->mb[2]);
2490fcf3ce44SJohn Forte } else {
2491fcf3ce44SJohn Forte /*EMPTY*/
2492*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2493fcf3ce44SJohn Forte }
2494fcf3ce44SJohn Forte
2495fcf3ce44SJohn Forte return (rval);
2496fcf3ce44SJohn Forte }
2497fcf3ce44SJohn Forte
2498fcf3ce44SJohn Forte /*
2499fcf3ce44SJohn Forte * ql_reset_link_status
2500fcf3ce44SJohn Forte * Issue Reset Link Error Status mailbox command
2501fcf3ce44SJohn Forte *
2502fcf3ce44SJohn Forte * Input:
2503fcf3ce44SJohn Forte * ha: adapter state pointer.
2504fcf3ce44SJohn Forte *
2505fcf3ce44SJohn Forte * Returns:
2506fcf3ce44SJohn Forte * ql local function return status code.
2507fcf3ce44SJohn Forte *
2508fcf3ce44SJohn Forte * Context:
2509fcf3ce44SJohn Forte * Kernel context.
2510fcf3ce44SJohn Forte */
2511fcf3ce44SJohn Forte int
ql_reset_link_status(ql_adapter_state_t * ha)2512fcf3ce44SJohn Forte ql_reset_link_status(ql_adapter_state_t *ha)
2513fcf3ce44SJohn Forte {
2514fcf3ce44SJohn Forte int rval;
2515fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2516fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2517fcf3ce44SJohn Forte
2518*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2519fcf3ce44SJohn Forte
2520fcf3ce44SJohn Forte mcp->mb[0] = MBC_RESET_LINK_STATUS;
2521fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
2522fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2523fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2524fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2525fcf3ce44SJohn Forte
2526fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2527fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
2528fcf3ce44SJohn Forte } else {
2529fcf3ce44SJohn Forte /*EMPTY*/
2530*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2531fcf3ce44SJohn Forte }
2532fcf3ce44SJohn Forte
2533fcf3ce44SJohn Forte return (rval);
2534fcf3ce44SJohn Forte }
2535fcf3ce44SJohn Forte
2536fcf3ce44SJohn Forte /*
2537fcf3ce44SJohn Forte * ql_loop_reset
2538fcf3ce44SJohn Forte * Issue loop reset.
2539fcf3ce44SJohn Forte *
2540fcf3ce44SJohn Forte * Input:
2541fcf3ce44SJohn Forte * ha: adapter state pointer.
2542fcf3ce44SJohn Forte *
2543fcf3ce44SJohn Forte * Returns:
2544fcf3ce44SJohn Forte * ql local function return status code.
2545fcf3ce44SJohn Forte *
2546fcf3ce44SJohn Forte * Context:
2547fcf3ce44SJohn Forte * Kernel context.
2548fcf3ce44SJohn Forte */
2549fcf3ce44SJohn Forte int
ql_loop_reset(ql_adapter_state_t * ha)2550fcf3ce44SJohn Forte ql_loop_reset(ql_adapter_state_t *ha)
2551fcf3ce44SJohn Forte {
2552fcf3ce44SJohn Forte int rval;
2553fcf3ce44SJohn Forte
2554*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2555fcf3ce44SJohn Forte
2556fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_ENABLE_LIP_RESET)) {
2557fcf3ce44SJohn Forte rval = ql_lip_reset(ha, 0xff);
2558fcf3ce44SJohn Forte } else if (CFG_IST(ha, CFG_ENABLE_FULL_LIP_LOGIN)) {
2559fcf3ce44SJohn Forte rval = ql_full_login_lip(ha);
2560fcf3ce44SJohn Forte } else if (CFG_IST(ha, CFG_ENABLE_TARGET_RESET)) {
2561fcf3ce44SJohn Forte rval = ql_target_reset(ha, NULL, ha->loop_reset_delay);
2562fcf3ce44SJohn Forte } else {
2563fcf3ce44SJohn Forte rval = ql_initiate_lip(ha);
2564fcf3ce44SJohn Forte }
2565fcf3ce44SJohn Forte
2566fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2567fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2568fcf3ce44SJohn Forte } else {
2569fcf3ce44SJohn Forte /*EMPTY*/
2570*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2571fcf3ce44SJohn Forte }
2572fcf3ce44SJohn Forte
2573fcf3ce44SJohn Forte return (rval);
2574fcf3ce44SJohn Forte }
2575fcf3ce44SJohn Forte
2576fcf3ce44SJohn Forte /*
2577fcf3ce44SJohn Forte * ql_initiate_lip
2578fcf3ce44SJohn Forte * Initiate LIP mailbox command.
2579fcf3ce44SJohn Forte *
2580fcf3ce44SJohn Forte * Input:
2581fcf3ce44SJohn Forte * ha: adapter state pointer.
2582fcf3ce44SJohn Forte *
2583fcf3ce44SJohn Forte * Returns:
2584fcf3ce44SJohn Forte * ql local function return status code.
2585fcf3ce44SJohn Forte *
2586fcf3ce44SJohn Forte * Context:
2587fcf3ce44SJohn Forte * Kernel context.
2588fcf3ce44SJohn Forte */
2589fcf3ce44SJohn Forte int
ql_initiate_lip(ql_adapter_state_t * ha)2590fcf3ce44SJohn Forte ql_initiate_lip(ql_adapter_state_t *ha)
2591fcf3ce44SJohn Forte {
2592fcf3ce44SJohn Forte int rval;
2593fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2594fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2595fcf3ce44SJohn Forte
2596*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2597fcf3ce44SJohn Forte
2598*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2599*4c3888b8SHans Rosenfeld ql_toggle_loop_state(ha);
2600*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "8081 done\n");
2601*4c3888b8SHans Rosenfeld return (QL_SUCCESS);
2602*4c3888b8SHans Rosenfeld }
2603*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2604fcf3ce44SJohn Forte mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2605*4c3888b8SHans Rosenfeld mcp->mb[1] = BIT_4;
2606fcf3ce44SJohn Forte mcp->mb[3] = ha->loop_reset_delay;
2607fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2608fcf3ce44SJohn Forte } else {
2609fcf3ce44SJohn Forte mcp->mb[0] = MBC_INITIATE_LIP;
2610fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
2611fcf3ce44SJohn Forte }
2612fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2613fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2614fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2615fcf3ce44SJohn Forte
2616fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2617fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2618fcf3ce44SJohn Forte } else {
2619fcf3ce44SJohn Forte /*EMPTY*/
2620*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2621fcf3ce44SJohn Forte }
2622fcf3ce44SJohn Forte
2623fcf3ce44SJohn Forte return (rval);
2624fcf3ce44SJohn Forte }
2625fcf3ce44SJohn Forte
2626fcf3ce44SJohn Forte /*
2627fcf3ce44SJohn Forte * ql_full_login_lip
2628fcf3ce44SJohn Forte * Issue full login LIP mailbox command.
2629fcf3ce44SJohn Forte *
2630fcf3ce44SJohn Forte * Input:
2631fcf3ce44SJohn Forte * ha: adapter state pointer.
2632fcf3ce44SJohn Forte *
2633fcf3ce44SJohn Forte * Returns:
2634fcf3ce44SJohn Forte * ql local function return status code.
2635fcf3ce44SJohn Forte *
2636fcf3ce44SJohn Forte * Context:
2637fcf3ce44SJohn Forte * Kernel context.
2638fcf3ce44SJohn Forte */
2639fcf3ce44SJohn Forte int
ql_full_login_lip(ql_adapter_state_t * ha)2640fcf3ce44SJohn Forte ql_full_login_lip(ql_adapter_state_t *ha)
2641fcf3ce44SJohn Forte {
2642fcf3ce44SJohn Forte int rval;
2643fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2644fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2645fcf3ce44SJohn Forte
2646*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2647fcf3ce44SJohn Forte
2648*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2649*4c3888b8SHans Rosenfeld ql_toggle_loop_state(ha);
2650*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "8081 done\n");
2651*4c3888b8SHans Rosenfeld return (QL_SUCCESS);
2652*4c3888b8SHans Rosenfeld }
2653fcf3ce44SJohn Forte mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2654*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FC_TYPE_2)) {
26555dfd244aSDaniel Beauregard mcp->mb[1] = BIT_3;
26565dfd244aSDaniel Beauregard }
2657fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2658fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2659fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2660fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2661fcf3ce44SJohn Forte
2662fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2663fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2664fcf3ce44SJohn Forte } else {
2665fcf3ce44SJohn Forte /*EMPTY*/
2666*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done");
2667fcf3ce44SJohn Forte }
2668fcf3ce44SJohn Forte
2669fcf3ce44SJohn Forte return (rval);
2670fcf3ce44SJohn Forte }
2671fcf3ce44SJohn Forte
2672fcf3ce44SJohn Forte /*
2673fcf3ce44SJohn Forte * ql_lip_reset
2674fcf3ce44SJohn Forte * Issue lip reset to a port.
2675fcf3ce44SJohn Forte *
2676fcf3ce44SJohn Forte * Input:
2677fcf3ce44SJohn Forte * ha: adapter state pointer.
2678fcf3ce44SJohn Forte * loop_id: FC loop id.
2679fcf3ce44SJohn Forte *
2680fcf3ce44SJohn Forte * Returns:
2681fcf3ce44SJohn Forte * ql local function return status code.
2682fcf3ce44SJohn Forte *
2683fcf3ce44SJohn Forte * Context:
2684fcf3ce44SJohn Forte * Kernel context.
2685fcf3ce44SJohn Forte */
2686fcf3ce44SJohn Forte int
ql_lip_reset(ql_adapter_state_t * ha,uint16_t loop_id)2687fcf3ce44SJohn Forte ql_lip_reset(ql_adapter_state_t *ha, uint16_t loop_id)
2688fcf3ce44SJohn Forte {
2689fcf3ce44SJohn Forte int rval;
2690fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2691fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2692fcf3ce44SJohn Forte
2693*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2694*4c3888b8SHans Rosenfeld
2695*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
2696*4c3888b8SHans Rosenfeld ql_toggle_loop_state(ha);
2697*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "8081 done\n");
2698*4c3888b8SHans Rosenfeld return (QL_SUCCESS);
2699*4c3888b8SHans Rosenfeld }
2700fcf3ce44SJohn Forte
2701*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FC_TYPE_2)) {
2702fcf3ce44SJohn Forte mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2703*4c3888b8SHans Rosenfeld mcp->mb[1] = BIT_6;
2704fcf3ce44SJohn Forte mcp->mb[3] = ha->loop_reset_delay;
2705fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2706fcf3ce44SJohn Forte } else {
2707fcf3ce44SJohn Forte mcp->mb[0] = MBC_LIP_RESET;
2708fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2709fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
2710fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
2711fcf3ce44SJohn Forte } else {
2712fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(loop_id << 8);
2713fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2714fcf3ce44SJohn Forte }
2715fcf3ce44SJohn Forte mcp->mb[2] = ha->loop_reset_delay;
2716fcf3ce44SJohn Forte }
2717fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2718fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2719fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2720fcf3ce44SJohn Forte
2721fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2722fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2723fcf3ce44SJohn Forte } else {
2724fcf3ce44SJohn Forte /*EMPTY*/
2725*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2726fcf3ce44SJohn Forte }
2727fcf3ce44SJohn Forte
2728fcf3ce44SJohn Forte return (rval);
2729fcf3ce44SJohn Forte }
2730fcf3ce44SJohn Forte
2731fcf3ce44SJohn Forte /*
2732fcf3ce44SJohn Forte * ql_abort_command
2733fcf3ce44SJohn Forte * Abort command aborts a specified IOCB.
2734fcf3ce44SJohn Forte *
2735fcf3ce44SJohn Forte * Input:
2736fcf3ce44SJohn Forte * ha: adapter state pointer.
2737fcf3ce44SJohn Forte * sp: SRB structure pointer.
2738fcf3ce44SJohn Forte *
2739fcf3ce44SJohn Forte * Returns:
2740fcf3ce44SJohn Forte * ql local function return status code.
2741fcf3ce44SJohn Forte *
2742fcf3ce44SJohn Forte * Context:
2743fcf3ce44SJohn Forte * Kernel context.
2744fcf3ce44SJohn Forte */
2745fcf3ce44SJohn Forte int
ql_abort_command(ql_adapter_state_t * ha,ql_srb_t * sp)2746fcf3ce44SJohn Forte ql_abort_command(ql_adapter_state_t *ha, ql_srb_t *sp)
2747fcf3ce44SJohn Forte {
2748fcf3ce44SJohn Forte int rval;
2749fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2750fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2751fcf3ce44SJohn Forte ql_tgt_t *tq = sp->lun_queue->target_queue;
2752fcf3ce44SJohn Forte
2753*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2754fcf3ce44SJohn Forte
2755*4c3888b8SHans Rosenfeld sp->flags |= SRB_ABORTING;
2756*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2757fcf3ce44SJohn Forte rval = ql_abort_cmd_iocb(ha, sp);
2758fcf3ce44SJohn Forte } else {
2759fcf3ce44SJohn Forte mcp->mb[0] = MBC_ABORT_COMMAND_IOCB;
2760fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_EXT_FW_INTERFACE)) {
2761fcf3ce44SJohn Forte mcp->mb[1] = tq->loop_id;
2762fcf3ce44SJohn Forte } else {
2763fcf3ce44SJohn Forte mcp->mb[1] = (uint16_t)(tq->loop_id << 8);
2764fcf3ce44SJohn Forte }
2765fcf3ce44SJohn Forte mcp->mb[2] = LSW(sp->handle);
2766fcf3ce44SJohn Forte mcp->mb[3] = MSW(sp->handle);
2767fcf3ce44SJohn Forte mcp->mb[6] = (uint16_t)(sp->flags & SRB_FCP_CMD_PKT ?
2768fcf3ce44SJohn Forte sp->lun_queue->lun_no : 0);
2769fcf3ce44SJohn Forte mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2770fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
2771fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2772fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2773fcf3ce44SJohn Forte }
2774fcf3ce44SJohn Forte
2775fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2776fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh, handle=%xh\n", rval,
2777fcf3ce44SJohn Forte tq->d_id.b24, sp->handle);
2778fcf3ce44SJohn Forte } else {
2779fcf3ce44SJohn Forte /*EMPTY*/
2780*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2781fcf3ce44SJohn Forte }
2782fcf3ce44SJohn Forte
2783fcf3ce44SJohn Forte return (rval);
2784fcf3ce44SJohn Forte }
2785fcf3ce44SJohn Forte
2786fcf3ce44SJohn Forte /*
2787fcf3ce44SJohn Forte * ql_abort_cmd_iocb
2788fcf3ce44SJohn Forte * Function issues abort command IOCB.
2789fcf3ce44SJohn Forte *
2790fcf3ce44SJohn Forte * Input:
2791fcf3ce44SJohn Forte * ha: adapter state pointer.
2792fcf3ce44SJohn Forte * sp: SRB structure pointer.
2793fcf3ce44SJohn Forte *
2794fcf3ce44SJohn Forte * Returns:
2795fcf3ce44SJohn Forte * ql local function return status code.
2796fcf3ce44SJohn Forte *
2797fcf3ce44SJohn Forte * Context:
2798fcf3ce44SJohn Forte * Interrupt or Kernel context, no mailbox commands allowed.
2799fcf3ce44SJohn Forte */
2800fcf3ce44SJohn Forte static int
ql_abort_cmd_iocb(ql_adapter_state_t * ha,ql_srb_t * sp)2801fcf3ce44SJohn Forte ql_abort_cmd_iocb(ql_adapter_state_t *ha, ql_srb_t *sp)
2802fcf3ce44SJohn Forte {
2803fcf3ce44SJohn Forte ql_mbx_iocb_t *pkt;
2804fcf3ce44SJohn Forte int rval;
2805fcf3ce44SJohn Forte uint32_t pkt_size;
2806fcf3ce44SJohn Forte uint16_t comp_status;
2807fcf3ce44SJohn Forte ql_tgt_t *tq = sp->lun_queue->target_queue;
2808fcf3ce44SJohn Forte
2809*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2810fcf3ce44SJohn Forte
2811fcf3ce44SJohn Forte pkt_size = sizeof (ql_mbx_iocb_t);
2812fcf3ce44SJohn Forte if ((pkt = kmem_zalloc(pkt_size, KM_SLEEP)) == NULL) {
2813fcf3ce44SJohn Forte EL(ha, "failed, kmem_zalloc\n");
2814fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2815fcf3ce44SJohn Forte }
2816fcf3ce44SJohn Forte
2817fcf3ce44SJohn Forte pkt->abo.entry_type = ABORT_CMD_TYPE;
2818fcf3ce44SJohn Forte pkt->abo.entry_count = 1;
2819fcf3ce44SJohn Forte pkt->abo.n_port_hdl = (uint16_t)LE_16(tq->loop_id);
2820*4c3888b8SHans Rosenfeld if (!CFG_IST(ha, CFG_CTRL_82XX)) {
2821f885d00fSDaniel Beauregard pkt->abo.options = AF_NO_ABTS;
2822f885d00fSDaniel Beauregard }
2823fcf3ce44SJohn Forte pkt->abo.cmd_handle = LE_32(sp->handle);
2824fcf3ce44SJohn Forte pkt->abo.target_id[0] = tq->d_id.b.al_pa;
2825fcf3ce44SJohn Forte pkt->abo.target_id[1] = tq->d_id.b.area;
2826fcf3ce44SJohn Forte pkt->abo.target_id[2] = tq->d_id.b.domain;
2827fcf3ce44SJohn Forte pkt->abo.vp_index = ha->vp_index;
2828fcf3ce44SJohn Forte
2829fcf3ce44SJohn Forte rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt, pkt_size);
2830fcf3ce44SJohn Forte
2831f885d00fSDaniel Beauregard if (rval == QL_SUCCESS) {
2832*4c3888b8SHans Rosenfeld if ((pkt->abo.entry_status & 0x3c) != 0) {
2833f885d00fSDaniel Beauregard EL(ha, "failed, entry_status=%xh, d_id=%xh\n",
2834f885d00fSDaniel Beauregard pkt->abo.entry_status, tq->d_id.b24);
2835f885d00fSDaniel Beauregard rval = QL_FUNCTION_PARAMETER_ERROR;
2836f885d00fSDaniel Beauregard } else {
2837f885d00fSDaniel Beauregard comp_status = (uint16_t)LE_16(pkt->abo.n_port_hdl);
2838f885d00fSDaniel Beauregard if (comp_status != CS_COMPLETE) {
2839f885d00fSDaniel Beauregard EL(ha, "failed, comp_status=%xh, d_id=%xh\n",
2840f885d00fSDaniel Beauregard comp_status, tq->d_id.b24);
2841f885d00fSDaniel Beauregard rval = QL_FUNCTION_FAILED;
2842f885d00fSDaniel Beauregard }
2843f885d00fSDaniel Beauregard }
2844fcf3ce44SJohn Forte }
2845fcf3ce44SJohn Forte
2846fcf3ce44SJohn Forte kmem_free(pkt, pkt_size);
2847fcf3ce44SJohn Forte
2848fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2849fcf3ce44SJohn Forte EL(ha, "failed=%xh, d_id=%xh\n", rval, tq->d_id.b24);
2850fcf3ce44SJohn Forte } else {
2851fcf3ce44SJohn Forte /*EMPTY*/
2852*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2853fcf3ce44SJohn Forte }
2854fcf3ce44SJohn Forte
2855fcf3ce44SJohn Forte return (rval);
2856fcf3ce44SJohn Forte }
2857fcf3ce44SJohn Forte
2858fcf3ce44SJohn Forte /*
2859fcf3ce44SJohn Forte * ql_verify_checksum
2860fcf3ce44SJohn Forte * Verify loaded RISC firmware.
2861fcf3ce44SJohn Forte *
2862fcf3ce44SJohn Forte * Input:
2863fcf3ce44SJohn Forte * ha = adapter state pointer.
2864fcf3ce44SJohn Forte *
2865fcf3ce44SJohn Forte * Returns:
2866fcf3ce44SJohn Forte * ql local function return status code.
2867fcf3ce44SJohn Forte *
2868fcf3ce44SJohn Forte * Context:
2869fcf3ce44SJohn Forte * Kernel context.
2870fcf3ce44SJohn Forte */
2871fcf3ce44SJohn Forte int
ql_verify_checksum(ql_adapter_state_t * ha)2872fcf3ce44SJohn Forte ql_verify_checksum(ql_adapter_state_t *ha)
2873fcf3ce44SJohn Forte {
2874fcf3ce44SJohn Forte int rval;
2875fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2876fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2877fcf3ce44SJohn Forte
2878*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2879fcf3ce44SJohn Forte
2880fcf3ce44SJohn Forte mcp->mb[0] = MBC_VERIFY_CHECKSUM;
2881*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2882fcf3ce44SJohn Forte mcp->mb[1] = MSW(ha->risc_fw[0].addr);
2883fcf3ce44SJohn Forte mcp->mb[2] = LSW(ha->risc_fw[0].addr);
2884fcf3ce44SJohn Forte } else {
2885fcf3ce44SJohn Forte mcp->mb[1] = LSW(ha->risc_fw[0].addr);
2886fcf3ce44SJohn Forte }
2887fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
2888fcf3ce44SJohn Forte mcp->in_mb = MBX_2|MBX_1|MBX_0;
2889fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2890fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2891fcf3ce44SJohn Forte
2892fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2893fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2894fcf3ce44SJohn Forte } else {
2895fcf3ce44SJohn Forte /*EMPTY*/
2896*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2897fcf3ce44SJohn Forte }
2898fcf3ce44SJohn Forte
2899fcf3ce44SJohn Forte return (rval);
2900fcf3ce44SJohn Forte }
2901fcf3ce44SJohn Forte
2902fcf3ce44SJohn Forte /*
2903fcf3ce44SJohn Forte * ql_get_id_list
2904fcf3ce44SJohn Forte * Get d_id and loop ID list.
2905fcf3ce44SJohn Forte *
2906fcf3ce44SJohn Forte * Input:
2907fcf3ce44SJohn Forte * ha: adapter state pointer.
2908fcf3ce44SJohn Forte * bp: data pointer for DMA data.
2909fcf3ce44SJohn Forte * size: size of data buffer.
2910fcf3ce44SJohn Forte * mr: pointer for mailbox data.
2911fcf3ce44SJohn Forte *
2912fcf3ce44SJohn Forte * Returns:
2913fcf3ce44SJohn Forte * ql local function return status code.
2914fcf3ce44SJohn Forte *
2915fcf3ce44SJohn Forte * Context:
2916fcf3ce44SJohn Forte * Kernel context.
2917fcf3ce44SJohn Forte */
2918fcf3ce44SJohn Forte int
ql_get_id_list(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,ql_mbx_data_t * mr)2919fcf3ce44SJohn Forte ql_get_id_list(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
2920fcf3ce44SJohn Forte ql_mbx_data_t *mr)
2921fcf3ce44SJohn Forte {
2922fcf3ce44SJohn Forte int rval;
2923fcf3ce44SJohn Forte dma_mem_t mem_desc;
2924fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2925fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
2926fcf3ce44SJohn Forte
2927*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
2928fcf3ce44SJohn Forte
2929fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
2930fcf3ce44SJohn Forte (uint32_t)size)) != QL_SUCCESS) {
2931fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
2932fcf3ce44SJohn Forte return (QL_MEMORY_ALLOC_FAILED);
2933fcf3ce44SJohn Forte }
2934fcf3ce44SJohn Forte
2935fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_ID_LIST;
2936*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
2937fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2938fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2939fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2940fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2941fcf3ce44SJohn Forte mcp->mb[8] = (uint16_t)size;
2942fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
2943fcf3ce44SJohn Forte mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2944fcf3ce44SJohn Forte } else {
2945fcf3ce44SJohn Forte mcp->mb[1] = MSW(LSD(mem_desc.cookie.dmac_laddress));
2946fcf3ce44SJohn Forte mcp->mb[2] = LSW(LSD(mem_desc.cookie.dmac_laddress));
2947fcf3ce44SJohn Forte mcp->mb[3] = MSW(MSD(mem_desc.cookie.dmac_laddress));
2948fcf3ce44SJohn Forte mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
2949fcf3ce44SJohn Forte mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2950fcf3ce44SJohn Forte }
2951fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
2952fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
2953fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
2954fcf3ce44SJohn Forte
2955fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
2956fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bp);
2957fcf3ce44SJohn Forte }
2958fcf3ce44SJohn Forte
2959fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
2960fcf3ce44SJohn Forte
2961fcf3ce44SJohn Forte /* Return mailbox data. */
2962fcf3ce44SJohn Forte if (mr != NULL) {
2963fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
2964fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
2965fcf3ce44SJohn Forte }
2966fcf3ce44SJohn Forte
2967fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
2968fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
2969fcf3ce44SJohn Forte } else {
2970fcf3ce44SJohn Forte /*EMPTY*/
2971*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
2972fcf3ce44SJohn Forte }
2973fcf3ce44SJohn Forte
2974fcf3ce44SJohn Forte return (rval);
2975fcf3ce44SJohn Forte }
2976fcf3ce44SJohn Forte
2977fcf3ce44SJohn Forte /*
2978fcf3ce44SJohn Forte * ql_wrt_risc_ram
2979fcf3ce44SJohn Forte * Load RISC RAM.
2980fcf3ce44SJohn Forte *
2981fcf3ce44SJohn Forte * Input:
2982fcf3ce44SJohn Forte * ha: adapter state pointer.
2983fcf3ce44SJohn Forte * risc_address: risc ram word address.
2984fcf3ce44SJohn Forte * bp: DMA pointer.
2985fcf3ce44SJohn Forte * word_count: 16/32bit word count.
2986fcf3ce44SJohn Forte *
2987fcf3ce44SJohn Forte * Returns:
2988fcf3ce44SJohn Forte * ql local function return status code.
2989fcf3ce44SJohn Forte *
2990fcf3ce44SJohn Forte * Context:
2991fcf3ce44SJohn Forte * Kernel context.
2992fcf3ce44SJohn Forte */
2993fcf3ce44SJohn Forte int
ql_wrt_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)2994fcf3ce44SJohn Forte ql_wrt_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
2995fcf3ce44SJohn Forte uint32_t word_count)
2996fcf3ce44SJohn Forte {
2997fcf3ce44SJohn Forte int rval;
2998fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
2999fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3000fcf3ce44SJohn Forte
3001*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3002fcf3ce44SJohn Forte
3003*4c3888b8SHans Rosenfeld mcp->mb[1] = LSW(risc_address);
3004*4c3888b8SHans Rosenfeld mcp->mb[2] = MSW(LSD(bp));
3005*4c3888b8SHans Rosenfeld mcp->mb[3] = LSW(LSD(bp));
3006*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3007fcf3ce44SJohn Forte mcp->mb[0] = MBC_LOAD_RAM_EXTENDED;
3008fcf3ce44SJohn Forte mcp->mb[4] = MSW(word_count);
3009fcf3ce44SJohn Forte mcp->mb[5] = LSW(word_count);
3010fcf3ce44SJohn Forte mcp->mb[8] = MSW(risc_address);
3011*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_8;
3012fcf3ce44SJohn Forte } else {
3013*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_LOAD_RISC_RAM;
3014fcf3ce44SJohn Forte mcp->mb[4] = LSW(word_count);
3015*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3016fcf3ce44SJohn Forte }
3017*4c3888b8SHans Rosenfeld mcp->mb[6] = MSW(MSD(bp));
3018*4c3888b8SHans Rosenfeld mcp->mb[7] = LSW(MSD(bp));
3019fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
3020fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3021fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3022fcf3ce44SJohn Forte
3023fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3024fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
3025fcf3ce44SJohn Forte } else {
3026fcf3ce44SJohn Forte /*EMPTY*/
3027*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3028fcf3ce44SJohn Forte }
3029fcf3ce44SJohn Forte
3030fcf3ce44SJohn Forte return (rval);
3031fcf3ce44SJohn Forte }
3032fcf3ce44SJohn Forte
3033fcf3ce44SJohn Forte /*
3034fcf3ce44SJohn Forte * ql_rd_risc_ram
3035fcf3ce44SJohn Forte * Get RISC RAM.
3036fcf3ce44SJohn Forte *
3037fcf3ce44SJohn Forte * Input:
3038fcf3ce44SJohn Forte * ha: adapter state pointer.
3039fcf3ce44SJohn Forte * risc_address: risc ram word address.
3040fcf3ce44SJohn Forte * bp: direct data pointer.
3041fcf3ce44SJohn Forte * word_count: 16/32bit word count.
3042fcf3ce44SJohn Forte *
3043fcf3ce44SJohn Forte * Returns:
3044fcf3ce44SJohn Forte * ql local function return status code.
3045fcf3ce44SJohn Forte *
3046fcf3ce44SJohn Forte * Context:
3047fcf3ce44SJohn Forte * Kernel context.
3048fcf3ce44SJohn Forte */
3049fcf3ce44SJohn Forte int
ql_rd_risc_ram(ql_adapter_state_t * ha,uint32_t risc_address,uint64_t bp,uint32_t word_count)3050fcf3ce44SJohn Forte ql_rd_risc_ram(ql_adapter_state_t *ha, uint32_t risc_address, uint64_t bp,
3051fcf3ce44SJohn Forte uint32_t word_count)
3052fcf3ce44SJohn Forte {
3053fcf3ce44SJohn Forte int rval;
3054fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3055fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3056fcf3ce44SJohn Forte
3057*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3058fcf3ce44SJohn Forte
3059*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3060fcf3ce44SJohn Forte mcp->mb[0] = MBC_DUMP_RAM_EXTENDED;
3061fcf3ce44SJohn Forte mcp->mb[1] = LSW(risc_address);
3062fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(bp));
3063fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(bp));
3064fcf3ce44SJohn Forte mcp->mb[4] = MSW(word_count);
3065fcf3ce44SJohn Forte mcp->mb[5] = LSW(word_count);
3066fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(bp));
3067fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(bp));
3068fcf3ce44SJohn Forte mcp->mb[8] = MSW(risc_address);
3069fcf3ce44SJohn Forte mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
3070fcf3ce44SJohn Forte MBX_0;
3071fcf3ce44SJohn Forte } else {
3072fcf3ce44SJohn Forte mcp->mb[0] = MBC_DUMP_RAM; /* doesn't support 64bit addr */
3073fcf3ce44SJohn Forte mcp->mb[1] = LSW(risc_address);
3074fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(bp));
3075fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(bp));
3076fcf3ce44SJohn Forte mcp->mb[4] = LSW(word_count);
3077fcf3ce44SJohn Forte mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3078fcf3ce44SJohn Forte }
3079fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
3080fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3081fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3082fcf3ce44SJohn Forte
3083fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3084fcf3ce44SJohn Forte EL(ha, "failed, rval = %xh\n", rval);
3085fcf3ce44SJohn Forte } else {
3086fcf3ce44SJohn Forte /*EMPTY*/
3087*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3088fcf3ce44SJohn Forte }
3089fcf3ce44SJohn Forte
3090fcf3ce44SJohn Forte return (rval);
3091fcf3ce44SJohn Forte }
3092fcf3ce44SJohn Forte
3093f33c1cdbSDaniel Beauregard /*
3094f33c1cdbSDaniel Beauregard * ql_wrt_risc_ram_word
3095f33c1cdbSDaniel Beauregard * Write RISC RAM word.
3096f33c1cdbSDaniel Beauregard *
3097f33c1cdbSDaniel Beauregard * Input:
3098f33c1cdbSDaniel Beauregard * ha: adapter state pointer.
3099f33c1cdbSDaniel Beauregard * risc_address: risc ram word address.
3100f33c1cdbSDaniel Beauregard * data: data.
3101f33c1cdbSDaniel Beauregard *
3102f33c1cdbSDaniel Beauregard * Returns:
3103f33c1cdbSDaniel Beauregard * ql local function return status code.
3104f33c1cdbSDaniel Beauregard *
3105f33c1cdbSDaniel Beauregard * Context:
3106f33c1cdbSDaniel Beauregard * Kernel context.
3107f33c1cdbSDaniel Beauregard */
3108f33c1cdbSDaniel Beauregard int
ql_wrt_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t data)3109f33c1cdbSDaniel Beauregard ql_wrt_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3110f33c1cdbSDaniel Beauregard uint32_t data)
3111f33c1cdbSDaniel Beauregard {
3112f33c1cdbSDaniel Beauregard int rval;
3113f33c1cdbSDaniel Beauregard mbx_cmd_t mc = {0};
3114f33c1cdbSDaniel Beauregard mbx_cmd_t *mcp = &mc;
3115f33c1cdbSDaniel Beauregard
3116*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3117f33c1cdbSDaniel Beauregard
3118f33c1cdbSDaniel Beauregard mcp->mb[0] = MBC_WRITE_RAM_EXTENDED;
3119f33c1cdbSDaniel Beauregard mcp->mb[1] = LSW(risc_address);
3120f33c1cdbSDaniel Beauregard mcp->mb[2] = LSW(data);
3121f33c1cdbSDaniel Beauregard mcp->mb[3] = MSW(data);
3122f33c1cdbSDaniel Beauregard mcp->mb[8] = MSW(risc_address);
3123f33c1cdbSDaniel Beauregard mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3124f33c1cdbSDaniel Beauregard mcp->in_mb = MBX_0;
3125f33c1cdbSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
3126f33c1cdbSDaniel Beauregard
3127f33c1cdbSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
3128f33c1cdbSDaniel Beauregard
3129f33c1cdbSDaniel Beauregard if (rval != QL_SUCCESS) {
3130f33c1cdbSDaniel Beauregard EL(ha, "failed, rval = %xh\n", rval);
3131f33c1cdbSDaniel Beauregard } else {
3132f33c1cdbSDaniel Beauregard /*EMPTY*/
3133*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3134f33c1cdbSDaniel Beauregard }
3135f33c1cdbSDaniel Beauregard
3136f33c1cdbSDaniel Beauregard return (rval);
3137f33c1cdbSDaniel Beauregard }
3138f33c1cdbSDaniel Beauregard
3139f33c1cdbSDaniel Beauregard /*
3140f33c1cdbSDaniel Beauregard * ql_rd_risc_ram_word
3141f33c1cdbSDaniel Beauregard * Read RISC RAM word.
3142f33c1cdbSDaniel Beauregard *
3143f33c1cdbSDaniel Beauregard * Input:
3144f33c1cdbSDaniel Beauregard * ha: adapter state pointer.
3145f33c1cdbSDaniel Beauregard * risc_address: risc ram word address.
3146f33c1cdbSDaniel Beauregard * data: data pointer.
3147f33c1cdbSDaniel Beauregard *
3148f33c1cdbSDaniel Beauregard * Returns:
3149f33c1cdbSDaniel Beauregard * ql local function return status code.
3150f33c1cdbSDaniel Beauregard *
3151f33c1cdbSDaniel Beauregard * Context:
3152f33c1cdbSDaniel Beauregard * Kernel context.
3153f33c1cdbSDaniel Beauregard */
3154f33c1cdbSDaniel Beauregard int
ql_rd_risc_ram_word(ql_adapter_state_t * ha,uint32_t risc_address,uint32_t * data)3155f33c1cdbSDaniel Beauregard ql_rd_risc_ram_word(ql_adapter_state_t *ha, uint32_t risc_address,
3156f33c1cdbSDaniel Beauregard uint32_t *data)
3157f33c1cdbSDaniel Beauregard {
3158f33c1cdbSDaniel Beauregard int rval;
3159f33c1cdbSDaniel Beauregard mbx_cmd_t mc = {0};
3160f33c1cdbSDaniel Beauregard mbx_cmd_t *mcp = &mc;
3161f33c1cdbSDaniel Beauregard
3162*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3163f33c1cdbSDaniel Beauregard
3164f33c1cdbSDaniel Beauregard mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3165f33c1cdbSDaniel Beauregard mcp->mb[1] = LSW(risc_address);
3166f33c1cdbSDaniel Beauregard mcp->mb[8] = MSW(risc_address);
3167f33c1cdbSDaniel Beauregard mcp->out_mb = MBX_8|MBX_1|MBX_0;
3168f33c1cdbSDaniel Beauregard mcp->in_mb = MBX_3|MBX_2|MBX_0;
3169f33c1cdbSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
3170f33c1cdbSDaniel Beauregard
3171f33c1cdbSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
3172f33c1cdbSDaniel Beauregard
3173f33c1cdbSDaniel Beauregard if (rval != QL_SUCCESS) {
3174f33c1cdbSDaniel Beauregard EL(ha, "failed, rval = %xh\n", rval);
3175f33c1cdbSDaniel Beauregard } else {
3176f33c1cdbSDaniel Beauregard *data = mcp->mb[2];
3177*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3178f33c1cdbSDaniel Beauregard *data |= mcp->mb[3] << 16;
3179f33c1cdbSDaniel Beauregard }
3180*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3181f33c1cdbSDaniel Beauregard }
3182f33c1cdbSDaniel Beauregard
3183f33c1cdbSDaniel Beauregard return (rval);
3184f33c1cdbSDaniel Beauregard }
3185f33c1cdbSDaniel Beauregard
3186fcf3ce44SJohn Forte /*
3187fcf3ce44SJohn Forte * ql_issue_mbx_iocb
3188fcf3ce44SJohn Forte * Issue IOCB using mailbox command
3189fcf3ce44SJohn Forte *
3190fcf3ce44SJohn Forte * Input:
3191fcf3ce44SJohn Forte * ha: adapter state pointer.
3192fcf3ce44SJohn Forte * bp: buffer pointer.
3193fcf3ce44SJohn Forte * size: buffer size.
3194fcf3ce44SJohn Forte *
3195fcf3ce44SJohn Forte * Returns:
3196fcf3ce44SJohn Forte * ql local function return status code.
3197fcf3ce44SJohn Forte *
3198fcf3ce44SJohn Forte * Context:
3199fcf3ce44SJohn Forte * Kernel context.
3200fcf3ce44SJohn Forte */
3201fcf3ce44SJohn Forte int
ql_issue_mbx_iocb(ql_adapter_state_t * ha,caddr_t bp,uint32_t size)3202fcf3ce44SJohn Forte ql_issue_mbx_iocb(ql_adapter_state_t *ha, caddr_t bp, uint32_t size)
3203fcf3ce44SJohn Forte {
3204fcf3ce44SJohn Forte int rval;
3205fcf3ce44SJohn Forte dma_mem_t mem_desc;
3206fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3207fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3208fcf3ce44SJohn Forte
3209*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3210fcf3ce44SJohn Forte
3211fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3212fcf3ce44SJohn Forte QL_SUCCESS) {
3213fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3214fcf3ce44SJohn Forte return (rval);
3215fcf3ce44SJohn Forte }
3216fcf3ce44SJohn Forte
3217fcf3ce44SJohn Forte mcp->mb[0] = MBC_EXECUTE_IOCB;
3218fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3219fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3220fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3221fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3222fcf3ce44SJohn Forte mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3223fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
3224fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV + 5;
3225fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3226fcf3ce44SJohn Forte
3227fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
3228fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bp);
3229fcf3ce44SJohn Forte }
3230fcf3ce44SJohn Forte
3231fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
3232fcf3ce44SJohn Forte
3233fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3234fcf3ce44SJohn Forte EL(ha, "failed=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
3235fcf3ce44SJohn Forte } else {
3236fcf3ce44SJohn Forte /*EMPTY*/
3237*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3238fcf3ce44SJohn Forte }
3239fcf3ce44SJohn Forte
3240fcf3ce44SJohn Forte return (rval);
3241fcf3ce44SJohn Forte }
3242fcf3ce44SJohn Forte
3243fcf3ce44SJohn Forte /*
3244fcf3ce44SJohn Forte * ql_mbx_wrap_test
3245fcf3ce44SJohn Forte * Mailbox register wrap test.
3246fcf3ce44SJohn Forte *
3247fcf3ce44SJohn Forte * Input:
3248fcf3ce44SJohn Forte * ha: adapter state pointer.
3249fcf3ce44SJohn Forte * mr: pointer for in/out mailbox data.
3250fcf3ce44SJohn Forte *
3251fcf3ce44SJohn Forte * Returns:
3252fcf3ce44SJohn Forte * ql local function return status code.
3253fcf3ce44SJohn Forte *
3254fcf3ce44SJohn Forte * Context:
3255fcf3ce44SJohn Forte * Kernel context.
3256fcf3ce44SJohn Forte */
3257fcf3ce44SJohn Forte int
ql_mbx_wrap_test(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3258fcf3ce44SJohn Forte ql_mbx_wrap_test(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3259fcf3ce44SJohn Forte {
3260fcf3ce44SJohn Forte int rval;
3261fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3262fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3263fcf3ce44SJohn Forte
3264*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started cfg=0x%llx\n", ha->cfg_flags);
3265*4c3888b8SHans Rosenfeld
3266*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
3267*4c3888b8SHans Rosenfeld if (mr == NULL) {
3268*4c3888b8SHans Rosenfeld mcp->mb[1] = 0xAAAA;
3269*4c3888b8SHans Rosenfeld mcp->mb[2] = 0x5555;
3270*4c3888b8SHans Rosenfeld mcp->mb[3] = 0xAA55;
3271*4c3888b8SHans Rosenfeld mcp->mb[4] = 0x55AA;
3272*4c3888b8SHans Rosenfeld mcp->mb[5] = 0xA5A5;
3273*4c3888b8SHans Rosenfeld mcp->mb[6] = 0x5A5A;
3274*4c3888b8SHans Rosenfeld mcp->mb[7] = 0x2525;
3275*4c3888b8SHans Rosenfeld } else {
3276fcf3ce44SJohn Forte mcp->mb[1] = mr->mb[1];
3277fcf3ce44SJohn Forte mcp->mb[2] = mr->mb[2];
3278fcf3ce44SJohn Forte mcp->mb[3] = mr->mb[3];
3279fcf3ce44SJohn Forte mcp->mb[4] = mr->mb[4];
3280fcf3ce44SJohn Forte mcp->mb[5] = mr->mb[5];
3281fcf3ce44SJohn Forte mcp->mb[6] = mr->mb[6];
3282fcf3ce44SJohn Forte mcp->mb[7] = mr->mb[7];
3283*4c3888b8SHans Rosenfeld }
3284*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3285*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3286*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
3287*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
3288*4c3888b8SHans Rosenfeld if (rval == QL_SUCCESS) {
3289*4c3888b8SHans Rosenfeld if (mr == NULL) {
3290*4c3888b8SHans Rosenfeld if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
3291*4c3888b8SHans Rosenfeld mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) {
3292*4c3888b8SHans Rosenfeld rval = QL_FUNCTION_FAILED;
3293*4c3888b8SHans Rosenfeld }
3294*4c3888b8SHans Rosenfeld if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
3295*4c3888b8SHans Rosenfeld mcp->mb[7] != 0x2525) {
3296*4c3888b8SHans Rosenfeld rval = QL_FUNCTION_FAILED;
3297*4c3888b8SHans Rosenfeld }
3298*4c3888b8SHans Rosenfeld } else {
3299*4c3888b8SHans Rosenfeld if (mcp->mb[1] != mr->mb[1] ||
3300*4c3888b8SHans Rosenfeld mcp->mb[2] != mr->mb[2] ||
3301*4c3888b8SHans Rosenfeld mcp->mb[3] != mr->mb[3] ||
3302*4c3888b8SHans Rosenfeld mcp->mb[4] != mr->mb[4]) {
3303*4c3888b8SHans Rosenfeld rval = QL_FUNCTION_FAILED;
3304*4c3888b8SHans Rosenfeld }
3305*4c3888b8SHans Rosenfeld if (mcp->mb[5] != mr->mb[5] ||
3306*4c3888b8SHans Rosenfeld mcp->mb[6] != mr->mb[6] ||
3307*4c3888b8SHans Rosenfeld mcp->mb[7] != mr->mb[7]) {
3308*4c3888b8SHans Rosenfeld rval = QL_FUNCTION_FAILED;
3309*4c3888b8SHans Rosenfeld }
3310fcf3ce44SJohn Forte }
3311fcf3ce44SJohn Forte }
3312fcf3ce44SJohn Forte
3313fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3314fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3315fcf3ce44SJohn Forte } else {
3316fcf3ce44SJohn Forte /*EMPTY*/
3317*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3318fcf3ce44SJohn Forte }
3319fcf3ce44SJohn Forte
3320fcf3ce44SJohn Forte return (rval);
3321fcf3ce44SJohn Forte }
3322fcf3ce44SJohn Forte
3323fcf3ce44SJohn Forte /*
3324fcf3ce44SJohn Forte * ql_execute_fw
3325fcf3ce44SJohn Forte * Start adapter firmware.
3326fcf3ce44SJohn Forte *
3327fcf3ce44SJohn Forte * Input:
3328fcf3ce44SJohn Forte * ha: adapter state pointer.
3329fcf3ce44SJohn Forte *
3330fcf3ce44SJohn Forte * Returns:
33315dfd244aSDaniel Beauregard * ql local function return status code.
3332fcf3ce44SJohn Forte *
3333fcf3ce44SJohn Forte * Context:
3334fcf3ce44SJohn Forte * Kernel context.
3335fcf3ce44SJohn Forte */
3336fcf3ce44SJohn Forte int
ql_execute_fw(ql_adapter_state_t * ha)3337fcf3ce44SJohn Forte ql_execute_fw(ql_adapter_state_t *ha)
3338fcf3ce44SJohn Forte {
3339fcf3ce44SJohn Forte int rval;
3340fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3341fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3342fcf3ce44SJohn Forte
3343*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3344fcf3ce44SJohn Forte
3345*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_82XX)) {
3346eb82ff87SDaniel Beauregard return (QL_SUCCESS);
3347eb82ff87SDaniel Beauregard }
3348eb82ff87SDaniel Beauregard
3349fcf3ce44SJohn Forte mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
3350*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3351fcf3ce44SJohn Forte mcp->mb[1] = MSW(ha->risc_fw[0].addr);
3352fcf3ce44SJohn Forte mcp->mb[2] = LSW(ha->risc_fw[0].addr);
3353fcf3ce44SJohn Forte } else {
3354fcf3ce44SJohn Forte mcp->mb[1] = LSW(ha->risc_fw[0].addr);
3355fcf3ce44SJohn Forte }
3356eb82ff87SDaniel Beauregard if (CFG_IST(ha, CFG_LR_SUPPORT)) {
3357eb82ff87SDaniel Beauregard mcp->mb[4] = BIT_0;
3358eb82ff87SDaniel Beauregard }
3359fcf3ce44SJohn Forte mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3360fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
3361fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3362fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3363fcf3ce44SJohn Forte
3364*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_22XX)) {
3365fcf3ce44SJohn Forte rval = QL_SUCCESS;
3366fcf3ce44SJohn Forte }
3367fcf3ce44SJohn Forte
3368fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3369fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3370fcf3ce44SJohn Forte } else {
3371fcf3ce44SJohn Forte /*EMPTY*/
3372*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3373fcf3ce44SJohn Forte }
3374fcf3ce44SJohn Forte
3375fcf3ce44SJohn Forte return (rval);
3376fcf3ce44SJohn Forte }
3377fcf3ce44SJohn Forte
3378fcf3ce44SJohn Forte /*
3379fcf3ce44SJohn Forte * ql_get_firmware_option
3380fcf3ce44SJohn Forte * Get Firmware Options Mailbox Command.
3381fcf3ce44SJohn Forte *
3382fcf3ce44SJohn Forte * Input:
3383fcf3ce44SJohn Forte * ha: adapter state pointer.
3384fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3385fcf3ce44SJohn Forte *
3386fcf3ce44SJohn Forte * Returns:
3387fcf3ce44SJohn Forte * ql local function return status code.
3388fcf3ce44SJohn Forte *
3389fcf3ce44SJohn Forte * Context:
3390fcf3ce44SJohn Forte * Kernel context.
3391fcf3ce44SJohn Forte */
3392fcf3ce44SJohn Forte int
ql_get_firmware_option(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3393fcf3ce44SJohn Forte ql_get_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3394fcf3ce44SJohn Forte {
3395fcf3ce44SJohn Forte int rval;
3396fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3397fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3398fcf3ce44SJohn Forte
3399*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3400fcf3ce44SJohn Forte
3401fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_FIRMWARE_OPTIONS;
3402fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
3403fcf3ce44SJohn Forte mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3404fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3405fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3406fcf3ce44SJohn Forte
3407fcf3ce44SJohn Forte /* Return mailbox data. */
3408fcf3ce44SJohn Forte if (mr != NULL) {
3409fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
3410fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
3411fcf3ce44SJohn Forte mr->mb[2] = mcp->mb[2];
3412fcf3ce44SJohn Forte mr->mb[3] = mcp->mb[3];
3413fcf3ce44SJohn Forte }
3414fcf3ce44SJohn Forte
3415fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3416fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3417fcf3ce44SJohn Forte } else {
3418fcf3ce44SJohn Forte /*EMPTY*/
3419*4c3888b8SHans Rosenfeld QL_PRINT_9(ha, "done\n");
3420fcf3ce44SJohn Forte }
3421fcf3ce44SJohn Forte
3422fcf3ce44SJohn Forte return (rval);
3423fcf3ce44SJohn Forte }
3424fcf3ce44SJohn Forte
3425fcf3ce44SJohn Forte /*
3426fcf3ce44SJohn Forte * ql_set_firmware_option
3427fcf3ce44SJohn Forte * Set Firmware Options Mailbox Command.
3428fcf3ce44SJohn Forte *
3429fcf3ce44SJohn Forte * Input:
3430fcf3ce44SJohn Forte * ha: adapter state pointer.
3431fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3432fcf3ce44SJohn Forte *
3433fcf3ce44SJohn Forte * Returns:
3434fcf3ce44SJohn Forte * ql local function return status code.
3435fcf3ce44SJohn Forte *
3436fcf3ce44SJohn Forte * Context:
3437fcf3ce44SJohn Forte * Kernel context.
3438fcf3ce44SJohn Forte */
3439fcf3ce44SJohn Forte int
ql_set_firmware_option(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3440fcf3ce44SJohn Forte ql_set_firmware_option(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3441fcf3ce44SJohn Forte {
3442fcf3ce44SJohn Forte int rval;
3443fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3444fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3445fcf3ce44SJohn Forte
3446*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3447fcf3ce44SJohn Forte
3448fcf3ce44SJohn Forte if (mr != NULL) {
3449fcf3ce44SJohn Forte mcp->mb[0] = MBC_SET_FIRMWARE_OPTIONS;
3450fcf3ce44SJohn Forte mcp->mb[1] = mr->mb[1];
3451fcf3ce44SJohn Forte mcp->mb[2] = mr->mb[2];
3452fcf3ce44SJohn Forte mcp->mb[3] = mr->mb[3];
3453fcf3ce44SJohn Forte mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3454fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
3455fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3456fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3457fcf3ce44SJohn Forte } else {
3458fcf3ce44SJohn Forte rval = QL_FUNCTION_PARAMETER_ERROR;
3459fcf3ce44SJohn Forte }
3460fcf3ce44SJohn Forte
3461fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3462fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3463fcf3ce44SJohn Forte } else {
3464fcf3ce44SJohn Forte /*EMPTY*/
3465*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3466fcf3ce44SJohn Forte }
3467fcf3ce44SJohn Forte
3468fcf3ce44SJohn Forte return (rval);
3469fcf3ce44SJohn Forte }
3470fcf3ce44SJohn Forte
3471fcf3ce44SJohn Forte /*
3472fcf3ce44SJohn Forte * ql_init_firmware
3473fcf3ce44SJohn Forte * Initialize firmware mailbox command.
3474fcf3ce44SJohn Forte *
3475fcf3ce44SJohn Forte * Input:
3476fcf3ce44SJohn Forte * ha: adapter state pointer.
3477fcf3ce44SJohn Forte * ha->init_ctrl_blk = setup for transmit.
3478fcf3ce44SJohn Forte *
3479fcf3ce44SJohn Forte * Returns:
3480fcf3ce44SJohn Forte * ql local function return status code.
3481fcf3ce44SJohn Forte *
3482fcf3ce44SJohn Forte * Context:
3483fcf3ce44SJohn Forte * Kernel context.
3484fcf3ce44SJohn Forte */
3485fcf3ce44SJohn Forte int
ql_init_firmware(ql_adapter_state_t * ha)3486fcf3ce44SJohn Forte ql_init_firmware(ql_adapter_state_t *ha)
3487fcf3ce44SJohn Forte {
3488fcf3ce44SJohn Forte int rval;
3489fcf3ce44SJohn Forte dma_mem_t mem_desc;
3490fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3491fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3492fcf3ce44SJohn Forte
3493*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3494fcf3ce44SJohn Forte
3495*4c3888b8SHans Rosenfeld if (ha->flags & MULTI_QUEUE) {
3496*4c3888b8SHans Rosenfeld WR32_MBAR_REG(ha, ha->req_q[0]->mbar_req_in, 0);
3497*4c3888b8SHans Rosenfeld WR32_MBAR_REG(ha, ha->rsp_queues[0]->mbar_rsp_out, 0);
3498*4c3888b8SHans Rosenfeld } else if (CFG_IST(ha, CFG_CTRL_82XX)) {
3499*4c3888b8SHans Rosenfeld ql_8021_wr_req_in(ha, 0);
3500eb82ff87SDaniel Beauregard WRT32_IO_REG(ha, req_out, 0);
3501eb82ff87SDaniel Beauregard WRT32_IO_REG(ha, resp_in, 0);
3502eb82ff87SDaniel Beauregard WRT32_IO_REG(ha, resp_out, 0);
3503*4c3888b8SHans Rosenfeld } else if (CFG_IST(ha, CFG_ISP_FW_TYPE_2)) {
3504fcf3ce44SJohn Forte WRT32_IO_REG(ha, req_in, 0);
3505fcf3ce44SJohn Forte WRT32_IO_REG(ha, resp_out, 0);
3506fcf3ce44SJohn Forte WRT32_IO_REG(ha, pri_req_in, 0);
3507fcf3ce44SJohn Forte WRT32_IO_REG(ha, atio_req_out, 0);
3508fcf3ce44SJohn Forte } else {
3509fcf3ce44SJohn Forte WRT16_IO_REG(ha, req_in, 0);
3510fcf3ce44SJohn Forte WRT16_IO_REG(ha, resp_out, 0);
3511fcf3ce44SJohn Forte }
3512*4c3888b8SHans Rosenfeld if (ha->req_q[0]->req_out_shadow_ptr) {
3513*4c3888b8SHans Rosenfeld *ha->req_q[0]->req_out_shadow_ptr = 0;
3514*4c3888b8SHans Rosenfeld }
3515*4c3888b8SHans Rosenfeld if (ha->rsp_queues[0]->rsp_in_shadow_ptr) {
3516*4c3888b8SHans Rosenfeld *ha->rsp_queues[0]->rsp_in_shadow_ptr = 0;
3517*4c3888b8SHans Rosenfeld }
3518fcf3ce44SJohn Forte
3519fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc,
3520fcf3ce44SJohn Forte (caddr_t)&ha->init_ctrl_blk, sizeof (ql_comb_init_cb_t))) !=
3521fcf3ce44SJohn Forte QL_SUCCESS) {
3522fcf3ce44SJohn Forte EL(ha, "dma setup failed=%xh\n", rval);
3523fcf3ce44SJohn Forte return (rval);
3524fcf3ce44SJohn Forte }
3525fcf3ce44SJohn Forte
3526fcf3ce44SJohn Forte mcp->mb[0] = (uint16_t)(ha->flags & VP_ENABLED ?
3527fcf3ce44SJohn Forte MBC_INITIALIZE_MULTI_ID_FW : MBC_INITIALIZE_FIRMWARE);
3528fcf3ce44SJohn Forte
3529fcf3ce44SJohn Forte if (CFG_IST(ha, CFG_SBUS_CARD)) {
3530*4c3888b8SHans Rosenfeld mcp->mb[1] = (uint16_t)(CFG_IST(ha, CFG_CTRL_22XX) ?
3531fcf3ce44SJohn Forte 0x204c : 0x52);
3532fcf3ce44SJohn Forte }
3533fcf3ce44SJohn Forte
3534fcf3ce44SJohn Forte mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3535fcf3ce44SJohn Forte mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3536fcf3ce44SJohn Forte mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3537fcf3ce44SJohn Forte mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3538*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_FCOE_SUPPORT)) {
35395dfd244aSDaniel Beauregard uint64_t ofst, addr;
35405dfd244aSDaniel Beauregard ql_init_24xx_cb_t *icb = (ql_init_24xx_cb_t *)
35415dfd244aSDaniel Beauregard &ha->init_ctrl_blk.cb24;
35425dfd244aSDaniel Beauregard
35435dfd244aSDaniel Beauregard mcp->mb[0] = MBC_INITIALIZE_MULTI_ID_FW;
35445dfd244aSDaniel Beauregard if (icb->ext_blk.version[0] | icb->ext_blk.version[1]) {
35455dfd244aSDaniel Beauregard ofst = (uintptr_t)&icb->ext_blk - (uintptr_t)icb;
35465dfd244aSDaniel Beauregard addr = mem_desc.cookie.dmac_laddress + ofst;
35475dfd244aSDaniel Beauregard mcp->mb[10] = MSW(LSD(addr));
35485dfd244aSDaniel Beauregard mcp->mb[11] = LSW(LSD(addr));
35495dfd244aSDaniel Beauregard mcp->mb[12] = MSW(MSD(addr));
35505dfd244aSDaniel Beauregard mcp->mb[13] = LSW(MSD(addr));
35515dfd244aSDaniel Beauregard mcp->mb[14] = sizeof (ql_ext_icb_8100_t);
35524f8b8adcSDaniel Beauregard mcp->mb[1] = BIT_0;
35535dfd244aSDaniel Beauregard }
35545dfd244aSDaniel Beauregard mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
35555dfd244aSDaniel Beauregard MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
35565dfd244aSDaniel Beauregard } else {
35575dfd244aSDaniel Beauregard mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
35585dfd244aSDaniel Beauregard }
35595dfd244aSDaniel Beauregard mcp->in_mb = MBX_5|MBX_4|MBX_2|MBX_0;
3560fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3561fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3562fcf3ce44SJohn Forte
3563fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
3564fcf3ce44SJohn Forte ha->sfp_stat = mcp->mb[2];
3565*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_82XX)) {
3566*4c3888b8SHans Rosenfeld (void) ql_8021_get_md_template(ha);
3567*4c3888b8SHans Rosenfeld } else {
3568*4c3888b8SHans Rosenfeld uint16_t i, opt;
3569*4c3888b8SHans Rosenfeld
3570*4c3888b8SHans Rosenfeld opt = ha->flags & NO_INTR_HANDSHAKE ?
3571*4c3888b8SHans Rosenfeld IMO_NONE : IMO_INTERRUPT_HANDSHAKE;
3572*4c3888b8SHans Rosenfeld if (ha->flags & QUEUE_SHADOW_PTRS) {
3573*4c3888b8SHans Rosenfeld opt |= IMO_QUEUE_POINTER_SHADOWING;
3574*4c3888b8SHans Rosenfeld }
3575*4c3888b8SHans Rosenfeld /* Initialize ha multi-response-queue request queue */
3576*4c3888b8SHans Rosenfeld if (ha->rsp_queues_cnt > 1) {
3577*4c3888b8SHans Rosenfeld rval = ql_init_req_q(ha, ha->req_q[1], opt);
3578*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
3579*4c3888b8SHans Rosenfeld EL(ha, "ql_init_req_q=%xh\n", rval);
3580*4c3888b8SHans Rosenfeld return (rval);
3581*4c3888b8SHans Rosenfeld }
3582*4c3888b8SHans Rosenfeld }
3583*4c3888b8SHans Rosenfeld /* Initialize multi-response queues */
3584*4c3888b8SHans Rosenfeld for (i = 1; i < ha->rsp_queues_cnt; i++) {
3585*4c3888b8SHans Rosenfeld rval = ql_init_rsp_q(ha, ha->rsp_queues[i],
3586*4c3888b8SHans Rosenfeld opt);
3587*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
3588*4c3888b8SHans Rosenfeld EL(ha, "ql_init_rsp_q=%xh\n", rval);
3589*4c3888b8SHans Rosenfeld return (rval);
3590*4c3888b8SHans Rosenfeld }
3591*4c3888b8SHans Rosenfeld }
3592*4c3888b8SHans Rosenfeld }
3593fcf3ce44SJohn Forte }
3594fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
3595fcf3ce44SJohn Forte
3596fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3597fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3598fcf3ce44SJohn Forte } else {
3599fcf3ce44SJohn Forte /*EMPTY*/
3600*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3601fcf3ce44SJohn Forte }
3602fcf3ce44SJohn Forte
3603fcf3ce44SJohn Forte return (rval);
3604fcf3ce44SJohn Forte }
3605fcf3ce44SJohn Forte
3606fcf3ce44SJohn Forte /*
3607fcf3ce44SJohn Forte * ql_get_firmware_state
3608fcf3ce44SJohn Forte * Get adapter firmware state.
3609fcf3ce44SJohn Forte *
3610fcf3ce44SJohn Forte * Input:
3611fcf3ce44SJohn Forte * ha: adapter state pointer.
3612fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3613fcf3ce44SJohn Forte *
3614fcf3ce44SJohn Forte * Returns:
3615fcf3ce44SJohn Forte * ql local function return status code.
3616fcf3ce44SJohn Forte *
3617fcf3ce44SJohn Forte * Context:
3618fcf3ce44SJohn Forte * Kernel context.
3619fcf3ce44SJohn Forte */
3620fcf3ce44SJohn Forte int
ql_get_firmware_state(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3621fcf3ce44SJohn Forte ql_get_firmware_state(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3622fcf3ce44SJohn Forte {
3623fcf3ce44SJohn Forte int rval;
3624fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3625fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3626fcf3ce44SJohn Forte
3627*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3628fcf3ce44SJohn Forte
3629fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
3630fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
3631*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_6;
3632fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3633fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3634fcf3ce44SJohn Forte
3635*4c3888b8SHans Rosenfeld ha->fw_state[0] = mcp->mb[0];
3636*4c3888b8SHans Rosenfeld ha->fw_state[1] = mcp->mb[1];
3637*4c3888b8SHans Rosenfeld ha->fw_state[2] = mcp->mb[2];
3638*4c3888b8SHans Rosenfeld ha->fw_state[3] = mcp->mb[3];
3639*4c3888b8SHans Rosenfeld ha->fw_state[4] = mcp->mb[4];
3640*4c3888b8SHans Rosenfeld ha->fw_state[5] = mcp->mb[5];
3641*4c3888b8SHans Rosenfeld ha->fw_state[6] = mcp->mb[6];
3642*4c3888b8SHans Rosenfeld
3643fcf3ce44SJohn Forte /* Return mailbox data. */
3644fcf3ce44SJohn Forte if (mr != NULL) {
3645fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
3646fcf3ce44SJohn Forte mr->mb[2] = mcp->mb[2];
3647fcf3ce44SJohn Forte mr->mb[3] = mcp->mb[3];
36484f8b8adcSDaniel Beauregard mr->mb[4] = mcp->mb[4];
36494f8b8adcSDaniel Beauregard mr->mb[5] = mcp->mb[5];
3650*4c3888b8SHans Rosenfeld mr->mb[6] = mcp->mb[6];
3651fcf3ce44SJohn Forte }
3652fcf3ce44SJohn Forte
3653fcf3ce44SJohn Forte ha->sfp_stat = mcp->mb[2];
3654fcf3ce44SJohn Forte
3655fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3656fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3657fcf3ce44SJohn Forte } else {
3658fcf3ce44SJohn Forte /*EMPTY*/
3659*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3660fcf3ce44SJohn Forte }
3661fcf3ce44SJohn Forte
3662fcf3ce44SJohn Forte return (rval);
3663fcf3ce44SJohn Forte }
3664fcf3ce44SJohn Forte
3665fcf3ce44SJohn Forte /*
3666fcf3ce44SJohn Forte * ql_get_adapter_id
3667fcf3ce44SJohn Forte * Get adapter ID and topology.
3668fcf3ce44SJohn Forte *
3669fcf3ce44SJohn Forte * Input:
3670fcf3ce44SJohn Forte * ha: adapter state pointer.
3671fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3672fcf3ce44SJohn Forte *
3673fcf3ce44SJohn Forte * Returns:
3674fcf3ce44SJohn Forte * ql local function return status code.
3675fcf3ce44SJohn Forte *
3676fcf3ce44SJohn Forte * Context:
3677fcf3ce44SJohn Forte * Kernel context.
3678fcf3ce44SJohn Forte */
3679fcf3ce44SJohn Forte int
ql_get_adapter_id(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3680fcf3ce44SJohn Forte ql_get_adapter_id(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3681fcf3ce44SJohn Forte {
3682*4c3888b8SHans Rosenfeld int i, rval;
3683fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3684fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3685fcf3ce44SJohn Forte
3686*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3687fcf3ce44SJohn Forte
3688fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_ID;
3689fcf3ce44SJohn Forte if (ha->flags & VP_ENABLED) {
3690fcf3ce44SJohn Forte mcp->mb[9] = ha->vp_index;
3691fcf3ce44SJohn Forte }
36925dfd244aSDaniel Beauregard mcp->out_mb = MBX_9|MBX_0;
3693*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_19;
3694fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
369516dd44c2SDaniel Beauregard
3696fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3697fcf3ce44SJohn Forte
3698fcf3ce44SJohn Forte /* Return mailbox data. */
3699fcf3ce44SJohn Forte if (mr != NULL) {
3700*4c3888b8SHans Rosenfeld for (i = 0; i < 20; i++) {
3701*4c3888b8SHans Rosenfeld mr->mb[i] = mcp->mb[i];
3702*4c3888b8SHans Rosenfeld }
3703fcf3ce44SJohn Forte }
3704fcf3ce44SJohn Forte
3705fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3706fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3707fcf3ce44SJohn Forte } else {
3708fcf3ce44SJohn Forte /*EMPTY*/
3709*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3710fcf3ce44SJohn Forte }
3711fcf3ce44SJohn Forte
3712fcf3ce44SJohn Forte return (rval);
3713fcf3ce44SJohn Forte }
3714fcf3ce44SJohn Forte
3715fcf3ce44SJohn Forte /*
3716fcf3ce44SJohn Forte * ql_get_fw_version
3717fcf3ce44SJohn Forte * Get firmware version.
3718fcf3ce44SJohn Forte *
3719fcf3ce44SJohn Forte * Input:
3720fcf3ce44SJohn Forte * ha: adapter state pointer.
3721fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3722fcf3ce44SJohn Forte *
3723fcf3ce44SJohn Forte * Returns:
3724fcf3ce44SJohn Forte * ql local function return status code.
3725fcf3ce44SJohn Forte *
3726fcf3ce44SJohn Forte * Context:
3727fcf3ce44SJohn Forte * Kernel context.
3728fcf3ce44SJohn Forte */
3729fcf3ce44SJohn Forte int
ql_get_fw_version(ql_adapter_state_t * ha,ql_mbx_data_t * mr,uint16_t timeout)3730eb82ff87SDaniel Beauregard ql_get_fw_version(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t timeout)
3731fcf3ce44SJohn Forte {
3732*4c3888b8SHans Rosenfeld int rval, i;
3733fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3734fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3735fcf3ce44SJohn Forte
3736*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3737fcf3ce44SJohn Forte
3738fcf3ce44SJohn Forte mcp->mb[0] = MBC_ABOUT_FIRMWARE;
3739fcf3ce44SJohn Forte mcp->out_mb = MBX_0;
3740*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_83XX)) {
3741*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_17;
3742*4c3888b8SHans Rosenfeld } else if (CFG_IST(ha, CFG_CTRL_27XX)) {
3743*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_25;
3744*4c3888b8SHans Rosenfeld } else {
3745*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_13;
3746*4c3888b8SHans Rosenfeld }
3747eb82ff87SDaniel Beauregard mcp->timeout = timeout;
3748fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3749fcf3ce44SJohn Forte
3750fcf3ce44SJohn Forte /* Return mailbox data. */
3751fcf3ce44SJohn Forte if (mr != NULL) {
3752*4c3888b8SHans Rosenfeld for (i = 0; i < ha->reg_off->mbox_cnt && mcp->in_mb; i++) {
3753*4c3888b8SHans Rosenfeld if (mcp->in_mb & MBX_0) {
3754*4c3888b8SHans Rosenfeld mr->mb[i] = mcp->mb[i];
3755*4c3888b8SHans Rosenfeld }
3756*4c3888b8SHans Rosenfeld mcp->in_mb >>= 1;
3757*4c3888b8SHans Rosenfeld }
3758fcf3ce44SJohn Forte }
3759fcf3ce44SJohn Forte
3760fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3761fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3762fcf3ce44SJohn Forte } else {
3763fcf3ce44SJohn Forte /*EMPTY*/
3764*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3765fcf3ce44SJohn Forte }
3766fcf3ce44SJohn Forte
3767fcf3ce44SJohn Forte return (rval);
3768fcf3ce44SJohn Forte }
3769fcf3ce44SJohn Forte
3770fcf3ce44SJohn Forte /*
3771fcf3ce44SJohn Forte * ql_data_rate
3772fcf3ce44SJohn Forte * Issue data rate Mailbox Command.
3773fcf3ce44SJohn Forte *
3774fcf3ce44SJohn Forte * Input:
3775fcf3ce44SJohn Forte * ha: adapter state pointer.
3776fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3777fcf3ce44SJohn Forte *
3778fcf3ce44SJohn Forte * Returns:
3779fcf3ce44SJohn Forte * ql local function return status code.
3780fcf3ce44SJohn Forte *
3781fcf3ce44SJohn Forte * Context:
3782fcf3ce44SJohn Forte * Kernel context.
3783fcf3ce44SJohn Forte */
3784fcf3ce44SJohn Forte int
ql_data_rate(ql_adapter_state_t * ha,ql_mbx_data_t * mr)3785fcf3ce44SJohn Forte ql_data_rate(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
3786fcf3ce44SJohn Forte {
3787fcf3ce44SJohn Forte int rval;
3788fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3789fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3790fcf3ce44SJohn Forte
3791*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3792fcf3ce44SJohn Forte
3793fcf3ce44SJohn Forte if (mr != NULL) {
3794fcf3ce44SJohn Forte mcp->mb[0] = MBC_DATA_RATE;
3795fcf3ce44SJohn Forte mcp->mb[1] = mr->mb[1];
3796fcf3ce44SJohn Forte mcp->mb[2] = mr->mb[2];
3797fcf3ce44SJohn Forte mcp->out_mb = MBX_2|MBX_1|MBX_0;
3798*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3799fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3800fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3801fcf3ce44SJohn Forte
3802fcf3ce44SJohn Forte /* Return mailbox data. */
3803fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
3804fcf3ce44SJohn Forte mr->mb[2] = mcp->mb[2];
3805*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
3806fcf3ce44SJohn Forte } else {
3807fcf3ce44SJohn Forte rval = QL_FUNCTION_PARAMETER_ERROR;
3808fcf3ce44SJohn Forte }
3809fcf3ce44SJohn Forte
3810fcf3ce44SJohn Forte ha->sfp_stat = mcp->mb[2];
3811fcf3ce44SJohn Forte
3812fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3813fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
3814fcf3ce44SJohn Forte } else {
3815fcf3ce44SJohn Forte /*EMPTY*/
3816*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3817fcf3ce44SJohn Forte }
3818fcf3ce44SJohn Forte
3819fcf3ce44SJohn Forte return (rval);
3820fcf3ce44SJohn Forte }
3821fcf3ce44SJohn Forte
3822fcf3ce44SJohn Forte /*
3823fcf3ce44SJohn Forte * ql_Diag_Loopback
3824fcf3ce44SJohn Forte * Issue Reset Link Status mailbox command
3825fcf3ce44SJohn Forte *
3826fcf3ce44SJohn Forte * Input:
3827fcf3ce44SJohn Forte * ha: adapter state pointer.
3828fcf3ce44SJohn Forte * bp: buffer pointer.
3829fcf3ce44SJohn Forte * size: buffer size.
3830fcf3ce44SJohn Forte * opt: command options.
3831fcf3ce44SJohn Forte * it_cnt: iteration count.
3832fcf3ce44SJohn Forte * mr: pointer for mailbox data.
3833fcf3ce44SJohn Forte *
3834fcf3ce44SJohn Forte * Returns:
3835fcf3ce44SJohn Forte * ql local function return status code.
3836fcf3ce44SJohn Forte *
3837fcf3ce44SJohn Forte * Context:
3838fcf3ce44SJohn Forte * Kernel context.
3839fcf3ce44SJohn Forte */
3840fcf3ce44SJohn Forte int
ql_diag_loopback(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,uint16_t opt,uint32_t it_cnt,ql_mbx_data_t * mr)3841*4c3888b8SHans Rosenfeld ql_diag_loopback(ql_adapter_state_t *ha, caddr_t bp, uint32_t size,
3842*4c3888b8SHans Rosenfeld uint16_t opt, uint32_t it_cnt, ql_mbx_data_t *mr)
3843fcf3ce44SJohn Forte {
3844fcf3ce44SJohn Forte int rval;
3845fcf3ce44SJohn Forte dma_mem_t mem_desc;
3846fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3847fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3848fcf3ce44SJohn Forte
3849*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3850fcf3ce44SJohn Forte
3851fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3852fcf3ce44SJohn Forte QL_SUCCESS) {
3853fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3854fcf3ce44SJohn Forte return (rval);
3855fcf3ce44SJohn Forte }
3856fcf3ce44SJohn Forte
3857fcf3ce44SJohn Forte mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3858fcf3ce44SJohn Forte mcp->mb[1] = opt;
3859*4c3888b8SHans Rosenfeld mcp->mb[2] = ha->fcoe_fcf_idx;
3860fcf3ce44SJohn Forte mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3861fcf3ce44SJohn Forte mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3862fcf3ce44SJohn Forte mcp->mb[10] = LSW(size);
3863fcf3ce44SJohn Forte mcp->mb[11] = MSW(size);
3864fcf3ce44SJohn Forte mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3865fcf3ce44SJohn Forte mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3866fcf3ce44SJohn Forte mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3867fcf3ce44SJohn Forte mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3868fcf3ce44SJohn Forte mcp->mb[18] = LSW(it_cnt);
3869fcf3ce44SJohn Forte mcp->mb[19] = MSW(it_cnt);
3870fcf3ce44SJohn Forte mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3871fcf3ce44SJohn Forte mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3872fcf3ce44SJohn Forte mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
38734f8b8adcSDaniel Beauregard MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3874fcf3ce44SJohn Forte mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3875fcf3ce44SJohn Forte mcp->timeout = it_cnt / 300;
3876fcf3ce44SJohn Forte if (mcp->timeout < MAILBOX_TOV) {
3877fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3878fcf3ce44SJohn Forte }
3879fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3880fcf3ce44SJohn Forte
3881fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
3882fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bp);
3883fcf3ce44SJohn Forte }
3884fcf3ce44SJohn Forte
3885fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
3886fcf3ce44SJohn Forte
3887fcf3ce44SJohn Forte /* Return mailbox data. */
3888fcf3ce44SJohn Forte if (mr != NULL) {
3889fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
3890fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
3891fcf3ce44SJohn Forte mr->mb[2] = mcp->mb[2];
3892fcf3ce44SJohn Forte mr->mb[3] = mcp->mb[3];
3893fcf3ce44SJohn Forte mr->mb[18] = mcp->mb[18];
3894fcf3ce44SJohn Forte mr->mb[19] = mcp->mb[19];
3895fcf3ce44SJohn Forte }
3896fcf3ce44SJohn Forte
3897fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3898eb82ff87SDaniel Beauregard EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
3899fcf3ce44SJohn Forte } else {
3900fcf3ce44SJohn Forte /*EMPTY*/
3901*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3902fcf3ce44SJohn Forte }
3903fcf3ce44SJohn Forte
3904fcf3ce44SJohn Forte return (rval);
3905fcf3ce44SJohn Forte }
3906fcf3ce44SJohn Forte
3907fcf3ce44SJohn Forte /*
3908fcf3ce44SJohn Forte * ql_diag_echo
3909fcf3ce44SJohn Forte * Issue Diag echo mailbox command. Valid for qla23xx HBA's.
3910fcf3ce44SJohn Forte *
3911fcf3ce44SJohn Forte * Input:
3912fcf3ce44SJohn Forte * ha: adapter state pointer.
3913fcf3ce44SJohn Forte * bp: buffer pointer.
3914fcf3ce44SJohn Forte * size: buffer size.
3915fcf3ce44SJohn Forte * opt: command options.
3916fcf3ce44SJohn Forte * mr: pointer to mailbox status.
3917fcf3ce44SJohn Forte *
3918fcf3ce44SJohn Forte * Returns:
3919fcf3ce44SJohn Forte * ql local function return status code.
3920fcf3ce44SJohn Forte *
3921fcf3ce44SJohn Forte * Context:
3922fcf3ce44SJohn Forte * Kernel context.
3923fcf3ce44SJohn Forte */
3924fcf3ce44SJohn Forte int
ql_diag_echo(ql_adapter_state_t * ha,caddr_t bp,uint32_t size,uint16_t opt,ql_mbx_data_t * mr)3925*4c3888b8SHans Rosenfeld ql_diag_echo(ql_adapter_state_t *ha, caddr_t bp, uint32_t size, uint16_t opt,
3926*4c3888b8SHans Rosenfeld ql_mbx_data_t *mr)
3927fcf3ce44SJohn Forte {
3928fcf3ce44SJohn Forte int rval;
3929fcf3ce44SJohn Forte dma_mem_t mem_desc;
3930fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
3931fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
3932fcf3ce44SJohn Forte
3933*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
3934fcf3ce44SJohn Forte
3935fcf3ce44SJohn Forte if ((rval = ql_setup_mbox_dma_transfer(ha, &mem_desc, bp, size)) !=
3936fcf3ce44SJohn Forte QL_SUCCESS) {
3937fcf3ce44SJohn Forte EL(ha, "setup_mbox_dma_transfer failed: %x\n", rval);
3938fcf3ce44SJohn Forte return (rval);
3939fcf3ce44SJohn Forte }
3940fcf3ce44SJohn Forte
3941fcf3ce44SJohn Forte mcp->mb[0] = MBC_ECHO;
3942f33c1cdbSDaniel Beauregard mcp->mb[1] = opt;
3943*4c3888b8SHans Rosenfeld mcp->mb[2] = ha->fcoe_fcf_idx;
3944fcf3ce44SJohn Forte mcp->mb[6] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3945fcf3ce44SJohn Forte mcp->mb[7] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3946fcf3ce44SJohn Forte mcp->mb[10] = LSW(size);
3947fcf3ce44SJohn Forte mcp->mb[14] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3948fcf3ce44SJohn Forte mcp->mb[15] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3949fcf3ce44SJohn Forte mcp->mb[16] = LSW(LSD(mem_desc.cookie.dmac_laddress));
3950fcf3ce44SJohn Forte mcp->mb[17] = MSW(LSD(mem_desc.cookie.dmac_laddress));
3951fcf3ce44SJohn Forte mcp->mb[20] = LSW(MSD(mem_desc.cookie.dmac_laddress));
3952fcf3ce44SJohn Forte mcp->mb[21] = MSW(MSD(mem_desc.cookie.dmac_laddress));
3953fcf3ce44SJohn Forte mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
39544f8b8adcSDaniel Beauregard MBX_14|MBX_10|MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
3955fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
3956fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
3957fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
3958fcf3ce44SJohn Forte
3959fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
3960fcf3ce44SJohn Forte ql_get_mbox_dma_data(&mem_desc, bp);
3961fcf3ce44SJohn Forte }
3962fcf3ce44SJohn Forte
3963fcf3ce44SJohn Forte ql_free_dma_resource(ha, &mem_desc);
3964fcf3ce44SJohn Forte
3965fcf3ce44SJohn Forte if (mr != NULL) {
3966fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
3967fcf3ce44SJohn Forte }
3968fcf3ce44SJohn Forte
3969fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
3970fcf3ce44SJohn Forte EL(ha, "failed=%xh, mb1=%xh\n", rval,
3971fcf3ce44SJohn Forte mcp->mb[1]);
3972fcf3ce44SJohn Forte } else {
3973fcf3ce44SJohn Forte /*EMPTY*/
3974*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
3975*4c3888b8SHans Rosenfeld }
3976*4c3888b8SHans Rosenfeld
3977*4c3888b8SHans Rosenfeld return (rval);
3978*4c3888b8SHans Rosenfeld }
3979*4c3888b8SHans Rosenfeld
3980*4c3888b8SHans Rosenfeld /*
3981*4c3888b8SHans Rosenfeld * ql_diag_beacon
3982*4c3888b8SHans Rosenfeld * Enable/Disable beaconing via mailbox command.
3983*4c3888b8SHans Rosenfeld *
3984*4c3888b8SHans Rosenfeld * Input:
3985*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
3986*4c3888b8SHans Rosenfeld * mr: pointer to mailbox in/out parameters.
3987*4c3888b8SHans Rosenfeld *
3988*4c3888b8SHans Rosenfeld * Returns:
3989*4c3888b8SHans Rosenfeld * ql local function return status code.
3990*4c3888b8SHans Rosenfeld *
3991*4c3888b8SHans Rosenfeld * Context:
3992*4c3888b8SHans Rosenfeld * Kernel context.
3993*4c3888b8SHans Rosenfeld */
3994*4c3888b8SHans Rosenfeld int
ql_diag_beacon(ql_adapter_state_t * ha,int cmd,ql_mbx_data_t * mr)3995*4c3888b8SHans Rosenfeld ql_diag_beacon(ql_adapter_state_t *ha, int cmd, ql_mbx_data_t *mr)
3996*4c3888b8SHans Rosenfeld {
3997*4c3888b8SHans Rosenfeld int rval;
3998*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
3999*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
4000*4c3888b8SHans Rosenfeld
4001*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_SET_LED_CONFIG;
4002*4c3888b8SHans Rosenfeld if (cmd == QL_BEACON_ENABLE) {
4003*4c3888b8SHans Rosenfeld mcp->mb[7] = 0xE;
4004*4c3888b8SHans Rosenfeld } else if (cmd == QL_BEACON_DISABLE) {
4005*4c3888b8SHans Rosenfeld mcp->mb[7] = 0xD;
4006*4c3888b8SHans Rosenfeld } else {
4007*4c3888b8SHans Rosenfeld return (EIO);
4008*4c3888b8SHans Rosenfeld }
4009*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_7|MBX_0;
4010*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0;
4011*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
4012*4c3888b8SHans Rosenfeld
4013*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
4014*4c3888b8SHans Rosenfeld
4015*4c3888b8SHans Rosenfeld /* Return mailbox data. */
4016*4c3888b8SHans Rosenfeld if (mr != NULL) {
4017*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
4018*4c3888b8SHans Rosenfeld }
4019*4c3888b8SHans Rosenfeld
4020*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
4021*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh\n", rval);
4022fcf3ce44SJohn Forte }
4023fcf3ce44SJohn Forte
4024fcf3ce44SJohn Forte return (rval);
4025fcf3ce44SJohn Forte }
4026fcf3ce44SJohn Forte
4027*4c3888b8SHans Rosenfeld
4028fcf3ce44SJohn Forte /*
4029fcf3ce44SJohn Forte * ql_serdes_param
4030fcf3ce44SJohn Forte * Set/Get serdes transmit parameters mailbox command.
4031fcf3ce44SJohn Forte *
4032fcf3ce44SJohn Forte * Input:
4033fcf3ce44SJohn Forte * ha: adapter state pointer.
4034fcf3ce44SJohn Forte * mr: pointer to mailbox in/out parameters.
4035fcf3ce44SJohn Forte *
4036fcf3ce44SJohn Forte * Returns:
4037fcf3ce44SJohn Forte * ql local function return status code.
4038fcf3ce44SJohn Forte *
4039fcf3ce44SJohn Forte * Context:
4040fcf3ce44SJohn Forte * Kernel context.
4041fcf3ce44SJohn Forte */
4042fcf3ce44SJohn Forte int
ql_serdes_param(ql_adapter_state_t * ha,ql_mbx_data_t * mr)4043fcf3ce44SJohn Forte ql_serdes_param(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
4044fcf3ce44SJohn Forte {
4045fcf3ce44SJohn Forte int rval;
4046fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4047fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4048fcf3ce44SJohn Forte
4049*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4050fcf3ce44SJohn Forte
4051fcf3ce44SJohn Forte mcp->mb[0] = MBC_SERDES_TRANSMIT_PARAMETERS;
4052fcf3ce44SJohn Forte mcp->mb[1] = mr->mb[1];
4053fcf3ce44SJohn Forte mcp->mb[2] = mr->mb[2];
4054fcf3ce44SJohn Forte mcp->mb[3] = mr->mb[3];
4055fcf3ce44SJohn Forte mcp->mb[4] = mr->mb[4];
4056fcf3ce44SJohn Forte mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4057fcf3ce44SJohn Forte mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
4058fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4059fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4060fcf3ce44SJohn Forte
4061fcf3ce44SJohn Forte /* Return mailbox data. */
4062*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
4063*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
4064*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
4065*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
4066fcf3ce44SJohn Forte
4067fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4068fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4069fcf3ce44SJohn Forte } else {
4070fcf3ce44SJohn Forte /*EMPTY*/
4071*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4072fcf3ce44SJohn Forte }
4073fcf3ce44SJohn Forte
4074fcf3ce44SJohn Forte return (rval);
4075fcf3ce44SJohn Forte }
4076fcf3ce44SJohn Forte
4077fcf3ce44SJohn Forte /*
4078fcf3ce44SJohn Forte * ql_get_timeout_parameters
4079fcf3ce44SJohn Forte * Issue get timeout parameters mailbox command.
4080fcf3ce44SJohn Forte *
4081fcf3ce44SJohn Forte * Input:
4082fcf3ce44SJohn Forte * ha: adapter state pointer.
4083fcf3ce44SJohn Forte * mr: pointer to mailbox in/out parameters.
4084fcf3ce44SJohn Forte *
4085fcf3ce44SJohn Forte * Returns:
4086fcf3ce44SJohn Forte * ql local function return status code.
4087fcf3ce44SJohn Forte *
4088fcf3ce44SJohn Forte * Context:
4089fcf3ce44SJohn Forte * Kernel context.
4090fcf3ce44SJohn Forte */
4091fcf3ce44SJohn Forte int
ql_get_timeout_parameters(ql_adapter_state_t * ha,uint16_t * tov)4092fcf3ce44SJohn Forte ql_get_timeout_parameters(ql_adapter_state_t *ha, uint16_t *tov)
4093fcf3ce44SJohn Forte {
4094fcf3ce44SJohn Forte int rval;
4095fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4096fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4097fcf3ce44SJohn Forte
4098*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4099fcf3ce44SJohn Forte
4100fcf3ce44SJohn Forte mcp->mb[0] = MBC_GET_TIMEOUT_PARAMETERS;
4101*4c3888b8SHans Rosenfeld mcp->mb[1] = ha->fcoe_fcf_idx;
4102*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_1|MBX_0;
4103fcf3ce44SJohn Forte mcp->in_mb = MBX_3|MBX_0;
4104fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4105fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4106fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
4107fcf3ce44SJohn Forte /* Get 2 * R_A_TOV in seconds */
4108*4c3888b8SHans Rosenfeld if (CFG_IST(ha, CFG_CTRL_22XX) || mcp->mb[3] == 0) {
4109fcf3ce44SJohn Forte *tov = R_A_TOV_DEFAULT;
4110fcf3ce44SJohn Forte } else {
4111fcf3ce44SJohn Forte *tov = (uint16_t)(mcp->mb[3] / 10);
4112fcf3ce44SJohn Forte if (mcp->mb[3] % 10 != 0) {
4113fcf3ce44SJohn Forte *tov = (uint16_t)(*tov + 1);
4114fcf3ce44SJohn Forte }
4115fcf3ce44SJohn Forte /*
4116fcf3ce44SJohn Forte * Adjust value to prevent driver timeout at the same
4117fcf3ce44SJohn Forte * time as device.
4118fcf3ce44SJohn Forte */
4119fcf3ce44SJohn Forte *tov = (uint16_t)(*tov + 5);
4120fcf3ce44SJohn Forte }
4121fcf3ce44SJohn Forte } else {
4122fcf3ce44SJohn Forte *tov = R_A_TOV_DEFAULT;
4123fcf3ce44SJohn Forte }
4124fcf3ce44SJohn Forte
4125fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4126fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4127fcf3ce44SJohn Forte } else {
4128fcf3ce44SJohn Forte /*EMPTY*/
4129*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4130fcf3ce44SJohn Forte }
4131fcf3ce44SJohn Forte
4132fcf3ce44SJohn Forte return (rval);
4133fcf3ce44SJohn Forte }
4134fcf3ce44SJohn Forte
4135fcf3ce44SJohn Forte /*
4136fcf3ce44SJohn Forte * ql_stop_firmware
4137fcf3ce44SJohn Forte * Issue stop firmware Mailbox Command.
4138fcf3ce44SJohn Forte *
4139fcf3ce44SJohn Forte * Input:
4140fcf3ce44SJohn Forte * ha: adapter state pointer.
4141fcf3ce44SJohn Forte *
4142fcf3ce44SJohn Forte * Returns:
4143fcf3ce44SJohn Forte * ql local function return status code.
4144fcf3ce44SJohn Forte *
4145fcf3ce44SJohn Forte * Context:
4146fcf3ce44SJohn Forte * Kernel context.
4147fcf3ce44SJohn Forte */
4148fcf3ce44SJohn Forte int
ql_stop_firmware(ql_adapter_state_t * ha)4149fcf3ce44SJohn Forte ql_stop_firmware(ql_adapter_state_t *ha)
4150fcf3ce44SJohn Forte {
4151fcf3ce44SJohn Forte int rval;
4152fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4153fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4154fcf3ce44SJohn Forte
4155*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4156fcf3ce44SJohn Forte
4157fcf3ce44SJohn Forte mcp->mb[0] = MBC_STOP_FIRMWARE;
4158eb82ff87SDaniel Beauregard mcp->out_mb = MBX_1|MBX_0;
4159fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
4160f885d00fSDaniel Beauregard mcp->timeout = 2;
4161fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4162fcf3ce44SJohn Forte
4163fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4164fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4165fcf3ce44SJohn Forte } else {
4166fcf3ce44SJohn Forte /*EMPTY*/
4167*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4168fcf3ce44SJohn Forte }
4169fcf3ce44SJohn Forte
4170fcf3ce44SJohn Forte return (rval);
4171fcf3ce44SJohn Forte }
4172fcf3ce44SJohn Forte
4173fcf3ce44SJohn Forte /*
4174fcf3ce44SJohn Forte * ql_read_sfp
4175fcf3ce44SJohn Forte * Issue Read SFP Mailbox command
4176fcf3ce44SJohn Forte *
4177fcf3ce44SJohn Forte * Input:
4178fcf3ce44SJohn Forte * ha: adapter state pointer.
4179fcf3ce44SJohn Forte * mem: pointer to dma memory object for command.
4180fcf3ce44SJohn Forte * dev: Device address (A0h or A2h).
4181*4c3888b8SHans Rosenfeld * addr: Data address on SFP EEPROM (0-255).
4182fcf3ce44SJohn Forte *
4183fcf3ce44SJohn Forte * Returns:
4184fcf3ce44SJohn Forte * ql local function return status code.
4185fcf3ce44SJohn Forte *
4186fcf3ce44SJohn Forte * Context:
4187fcf3ce44SJohn Forte * Kernel context.
4188fcf3ce44SJohn Forte */
4189fcf3ce44SJohn Forte int
ql_read_sfp(ql_adapter_state_t * ha,dma_mem_t * mem,uint16_t dev,uint16_t addr)4190fcf3ce44SJohn Forte ql_read_sfp(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t dev,
4191fcf3ce44SJohn Forte uint16_t addr)
4192fcf3ce44SJohn Forte {
4193fcf3ce44SJohn Forte int rval;
4194fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4195fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4196fcf3ce44SJohn Forte
4197*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4198fcf3ce44SJohn Forte
4199fcf3ce44SJohn Forte mcp->mb[0] = MBC_READ_SFP;
4200fcf3ce44SJohn Forte mcp->mb[1] = dev;
4201fcf3ce44SJohn Forte mcp->mb[2] = MSW(mem->cookies->dmac_address);
4202fcf3ce44SJohn Forte mcp->mb[3] = LSW(mem->cookies->dmac_address);
4203fcf3ce44SJohn Forte mcp->mb[6] = MSW(mem->cookies->dmac_notused);
4204fcf3ce44SJohn Forte mcp->mb[7] = LSW(mem->cookies->dmac_notused);
4205fcf3ce44SJohn Forte mcp->mb[8] = LSW(mem->size);
4206fcf3ce44SJohn Forte mcp->mb[9] = addr;
4207fcf3ce44SJohn Forte mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4208fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
4209fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4210fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4211fcf3ce44SJohn Forte
4212fcf3ce44SJohn Forte (void) ddi_dma_sync(mem->dma_handle, 0, mem->size,
4213fcf3ce44SJohn Forte DDI_DMA_SYNC_FORKERNEL);
4214fcf3ce44SJohn Forte
4215fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4216fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4217fcf3ce44SJohn Forte } else {
4218fcf3ce44SJohn Forte /*EMPTY*/
4219*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4220fcf3ce44SJohn Forte }
4221fcf3ce44SJohn Forte
4222fcf3ce44SJohn Forte return (rval);
4223fcf3ce44SJohn Forte }
4224fcf3ce44SJohn Forte
4225fcf3ce44SJohn Forte /*
4226fcf3ce44SJohn Forte * ql_iidma_rate
4227fcf3ce44SJohn Forte * Issue get/set iidma rate command
4228fcf3ce44SJohn Forte *
4229fcf3ce44SJohn Forte * Input:
4230fcf3ce44SJohn Forte * ha: adapter state pointer.
4231fcf3ce44SJohn Forte * loop_id: n-port handle to set/get iidma rate.
4232fcf3ce44SJohn Forte * idma_rate: Pointer to iidma rate.
4233fcf3ce44SJohn Forte * option: iidma firmware option (set or get data).
4234fcf3ce44SJohn Forte * 0 --> Get iidma rate
4235fcf3ce44SJohn Forte * 1 --> Set iidma rate
4236fcf3ce44SJohn Forte *
4237fcf3ce44SJohn Forte * Returns:
4238fcf3ce44SJohn Forte * ql local function return status code.
4239fcf3ce44SJohn Forte *
4240fcf3ce44SJohn Forte * Context:
4241fcf3ce44SJohn Forte * Kernel context.
4242fcf3ce44SJohn Forte */
4243fcf3ce44SJohn Forte int
ql_iidma_rate(ql_adapter_state_t * ha,uint16_t loop_id,uint32_t * idma_rate,uint32_t option)4244fcf3ce44SJohn Forte ql_iidma_rate(ql_adapter_state_t *ha, uint16_t loop_id, uint32_t *idma_rate,
4245fcf3ce44SJohn Forte uint32_t option)
4246fcf3ce44SJohn Forte {
4247fcf3ce44SJohn Forte int rval;
4248fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4249fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4250fcf3ce44SJohn Forte
4251*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4252fcf3ce44SJohn Forte
4253fcf3ce44SJohn Forte mcp->mb[0] = MBC_PORT_PARAM;
4254fcf3ce44SJohn Forte mcp->mb[1] = loop_id;
4255fcf3ce44SJohn Forte mcp->mb[2] = (uint16_t)option;
4256fcf3ce44SJohn Forte mcp->out_mb = MBX_0|MBX_1|MBX_2;
4257fcf3ce44SJohn Forte mcp->in_mb = MBX_0|MBX_1;
4258fcf3ce44SJohn Forte
4259fcf3ce44SJohn Forte if (option & BIT_0) {
4260fcf3ce44SJohn Forte mcp->mb[3] = (uint16_t)*idma_rate;
4261fcf3ce44SJohn Forte mcp->out_mb |= MBX_3;
4262fcf3ce44SJohn Forte } else {
4263fcf3ce44SJohn Forte mcp->in_mb |= MBX_3;
4264fcf3ce44SJohn Forte }
4265fcf3ce44SJohn Forte
4266fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4267fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4268fcf3ce44SJohn Forte
4269fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4270fcf3ce44SJohn Forte EL(ha, "failed=%xh, mb1=%xh\n", rval, mcp->mb[1]);
4271fcf3ce44SJohn Forte } else {
4272fcf3ce44SJohn Forte if (option == 0) {
4273fcf3ce44SJohn Forte *idma_rate = mcp->mb[3];
4274fcf3ce44SJohn Forte }
4275fcf3ce44SJohn Forte
4276*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4277fcf3ce44SJohn Forte }
4278fcf3ce44SJohn Forte
4279fcf3ce44SJohn Forte return (rval);
4280fcf3ce44SJohn Forte }
4281fcf3ce44SJohn Forte
4282fcf3ce44SJohn Forte /*
4283fcf3ce44SJohn Forte * ql_set_xmit_parms
4284fcf3ce44SJohn Forte * Set transmit parameters
4285fcf3ce44SJohn Forte *
4286fcf3ce44SJohn Forte * Input:
4287fcf3ce44SJohn Forte * ha: adapter state pointer.
4288fcf3ce44SJohn Forte *
4289fcf3ce44SJohn Forte * Returns:
4290fcf3ce44SJohn Forte * ql local function return status code.
4291fcf3ce44SJohn Forte *
4292fcf3ce44SJohn Forte * Context:
4293fcf3ce44SJohn Forte * Kernel context.
4294fcf3ce44SJohn Forte */
4295fcf3ce44SJohn Forte int
ql_set_xmit_parms(ql_adapter_state_t * ha)4296fcf3ce44SJohn Forte ql_set_xmit_parms(ql_adapter_state_t *ha)
4297fcf3ce44SJohn Forte {
4298fcf3ce44SJohn Forte int rval;
4299fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4300fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4301fcf3ce44SJohn Forte
4302*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4303fcf3ce44SJohn Forte
4304fcf3ce44SJohn Forte mcp->mb[0] = MBC_XMIT_PARM;
4305fcf3ce44SJohn Forte mcp->mb[1] = BIT_1;
4306fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
4307fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
4308fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4309fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4310fcf3ce44SJohn Forte
4311fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4312fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4313fcf3ce44SJohn Forte } else {
4314fcf3ce44SJohn Forte /*EMPTY*/
4315*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4316fcf3ce44SJohn Forte }
4317fcf3ce44SJohn Forte return (rval);
4318fcf3ce44SJohn Forte }
4319fcf3ce44SJohn Forte
4320fcf3ce44SJohn Forte /*
4321fcf3ce44SJohn Forte * ql_fw_etrace
4322fcf3ce44SJohn Forte * Firmware extended tracing.
4323fcf3ce44SJohn Forte *
4324fcf3ce44SJohn Forte * Input:
4325fcf3ce44SJohn Forte * ha: adapter state pointer.
4326fcf3ce44SJohn Forte * mem: pointer to dma memory object for command.
432716dd44c2SDaniel Beauregard * opt: options and opcode.
4328*4c3888b8SHans Rosenfeld * mr: pointer to mailbox in/out parameters.
4329fcf3ce44SJohn Forte *
4330fcf3ce44SJohn Forte * Returns:
4331fcf3ce44SJohn Forte * ql local function return status code.
4332fcf3ce44SJohn Forte *
4333fcf3ce44SJohn Forte * Context:
4334fcf3ce44SJohn Forte * Kernel context.
4335fcf3ce44SJohn Forte */
4336fcf3ce44SJohn Forte int
ql_fw_etrace(ql_adapter_state_t * ha,dma_mem_t * mem,uint16_t opt,ql_mbx_data_t * mr)4337*4c3888b8SHans Rosenfeld ql_fw_etrace(ql_adapter_state_t *ha, dma_mem_t *mem, uint16_t opt,
4338*4c3888b8SHans Rosenfeld ql_mbx_data_t *mr)
4339fcf3ce44SJohn Forte {
4340fcf3ce44SJohn Forte int rval = QL_SUCCESS;
4341fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4342fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
434316dd44c2SDaniel Beauregard uint16_t op_code;
434416dd44c2SDaniel Beauregard uint64_t time;
4345fcf3ce44SJohn Forte
4346*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4347fcf3ce44SJohn Forte
434816dd44c2SDaniel Beauregard /* currently no supported options */
434916dd44c2SDaniel Beauregard op_code = (uint16_t)(opt & ~0xFF00);
435016dd44c2SDaniel Beauregard
4351fcf3ce44SJohn Forte mcp->mb[0] = MBC_TRACE_CONTROL;
435216dd44c2SDaniel Beauregard mcp->mb[1] = op_code;
4353fcf3ce44SJohn Forte mcp->in_mb = MBX_0;
4354fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4355fcf3ce44SJohn Forte
435616dd44c2SDaniel Beauregard switch (op_code) {
435716dd44c2SDaniel Beauregard case FTO_INSERT_TIME_STAMP:
435816dd44c2SDaniel Beauregard
435916dd44c2SDaniel Beauregard (void) drv_getparm(TIME, &time);
436016dd44c2SDaniel Beauregard
436116dd44c2SDaniel Beauregard EL(ha, "insert time: %x %xh\n", MSD(time), LSD(time));
436216dd44c2SDaniel Beauregard
436316dd44c2SDaniel Beauregard mcp->mb[2] = LSW(LSD(time));
436416dd44c2SDaniel Beauregard mcp->mb[3] = MSW(LSD(time));
436516dd44c2SDaniel Beauregard mcp->mb[4] = LSW(MSD(time));
436616dd44c2SDaniel Beauregard mcp->mb[5] = MSW(MSD(time));
436716dd44c2SDaniel Beauregard mcp->out_mb = MBX_0_THRU_5;
436816dd44c2SDaniel Beauregard break;
436916dd44c2SDaniel Beauregard
437016dd44c2SDaniel Beauregard case FTO_FCE_TRACE_ENABLE:
437116dd44c2SDaniel Beauregard /* Firmware Fibre Channel Event Trace Buffer */
4372fcf3ce44SJohn Forte mcp->mb[2] = LSW(mem->cookies->dmac_address);
4373fcf3ce44SJohn Forte mcp->mb[3] = MSW(mem->cookies->dmac_address);
4374fcf3ce44SJohn Forte mcp->mb[4] = LSW(mem->cookies->dmac_notused);
4375fcf3ce44SJohn Forte mcp->mb[5] = MSW(mem->cookies->dmac_notused);
4376fcf3ce44SJohn Forte mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
437716dd44c2SDaniel Beauregard mcp->mb[8] = (uint16_t)ha->fwfcetraceopt;
437816dd44c2SDaniel Beauregard mcp->mb[9] = FTO_FCEMAXTRACEBUF;
437916dd44c2SDaniel Beauregard mcp->mb[10] = FTO_FCEMAXTRACEBUF;
438016dd44c2SDaniel Beauregard mcp->out_mb = MBX_0_THRU_10;
438116dd44c2SDaniel Beauregard break;
438216dd44c2SDaniel Beauregard
438316dd44c2SDaniel Beauregard case FTO_EXT_TRACE_ENABLE:
438416dd44c2SDaniel Beauregard /* Firmware Extended Trace Buffer */
438516dd44c2SDaniel Beauregard mcp->mb[2] = LSW(mem->cookies->dmac_address);
438616dd44c2SDaniel Beauregard mcp->mb[3] = MSW(mem->cookies->dmac_address);
438716dd44c2SDaniel Beauregard mcp->mb[4] = LSW(mem->cookies->dmac_notused);
438816dd44c2SDaniel Beauregard mcp->mb[5] = MSW(mem->cookies->dmac_notused);
438916dd44c2SDaniel Beauregard mcp->mb[6] = (uint16_t)(mem->size / 0x4000); /* 16kb blks */
439016dd44c2SDaniel Beauregard mcp->out_mb = MBX_0_THRU_7;
4391fcf3ce44SJohn Forte break;
4392fcf3ce44SJohn Forte
439316dd44c2SDaniel Beauregard case FTO_FCE_TRACE_DISABLE:
439416dd44c2SDaniel Beauregard /* also causes ISP25xx to flush its internal FCE buffer. */
4395fcf3ce44SJohn Forte mcp->mb[2] = BIT_0;
439616dd44c2SDaniel Beauregard mcp->out_mb = MBX_0_THRU_2;
4397fcf3ce44SJohn Forte break;
4398fcf3ce44SJohn Forte
439916dd44c2SDaniel Beauregard case FTO_EXT_TRACE_DISABLE:
440016dd44c2SDaniel Beauregard /* just sending the opcode disables it */
4401fcf3ce44SJohn Forte break;
4402fcf3ce44SJohn Forte
4403fcf3ce44SJohn Forte default:
4404fcf3ce44SJohn Forte EL(ha, "invalid option: %xh\n", opt);
4405fcf3ce44SJohn Forte rval = QL_PARAMETER_ERROR;
4406fcf3ce44SJohn Forte break;
4407fcf3ce44SJohn Forte }
4408fcf3ce44SJohn Forte
4409fcf3ce44SJohn Forte if (rval == QL_SUCCESS) {
4410fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4411fcf3ce44SJohn Forte }
4412fcf3ce44SJohn Forte
4413*4c3888b8SHans Rosenfeld /* Return mailbox data. */
4414*4c3888b8SHans Rosenfeld if (mr != NULL) {
4415*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
4416*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
4417*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
4418*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
4419*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
4420*4c3888b8SHans Rosenfeld mr->mb[5] = mcp->mb[5];
4421*4c3888b8SHans Rosenfeld mr->mb[6] = mcp->mb[6];
4422*4c3888b8SHans Rosenfeld mr->mb[7] = mcp->mb[7];
4423*4c3888b8SHans Rosenfeld mr->mb[8] = mcp->mb[8];
4424*4c3888b8SHans Rosenfeld mr->mb[9] = mcp->mb[9];
4425*4c3888b8SHans Rosenfeld }
4426*4c3888b8SHans Rosenfeld
4427fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4428fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4429fcf3ce44SJohn Forte } else {
4430fcf3ce44SJohn Forte /*EMPTY*/
4431*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4432fcf3ce44SJohn Forte }
4433fcf3ce44SJohn Forte
4434fcf3ce44SJohn Forte return (rval);
4435fcf3ce44SJohn Forte }
4436fcf3ce44SJohn Forte
4437fcf3ce44SJohn Forte /*
4438fcf3ce44SJohn Forte * ql_reset_menlo
4439fcf3ce44SJohn Forte * Reset Menlo Mailbox Command.
4440fcf3ce44SJohn Forte *
4441fcf3ce44SJohn Forte * Input:
4442fcf3ce44SJohn Forte * ha: adapter state pointer.
4443fcf3ce44SJohn Forte * mr: pointer to mailbox in/out parameters.
4444fcf3ce44SJohn Forte * opt: options.
4445fcf3ce44SJohn Forte *
4446fcf3ce44SJohn Forte * Returns:
4447fcf3ce44SJohn Forte * ql local function return status code.
4448fcf3ce44SJohn Forte *
4449fcf3ce44SJohn Forte * Context:
4450fcf3ce44SJohn Forte * Kernel context.
4451fcf3ce44SJohn Forte */
4452fcf3ce44SJohn Forte int
ql_reset_menlo(ql_adapter_state_t * ha,ql_mbx_data_t * mr,uint16_t opt)4453fcf3ce44SJohn Forte ql_reset_menlo(ql_adapter_state_t *ha, ql_mbx_data_t *mr, uint16_t opt)
4454fcf3ce44SJohn Forte {
4455fcf3ce44SJohn Forte int rval;
4456fcf3ce44SJohn Forte mbx_cmd_t mc = {0};
4457fcf3ce44SJohn Forte mbx_cmd_t *mcp = &mc;
4458fcf3ce44SJohn Forte
4459*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4460fcf3ce44SJohn Forte
4461fcf3ce44SJohn Forte mcp->mb[0] = MBC_RESET_MENLO;
4462fcf3ce44SJohn Forte mcp->mb[1] = opt;
4463fcf3ce44SJohn Forte mcp->out_mb = MBX_1|MBX_0;
4464fcf3ce44SJohn Forte mcp->in_mb = MBX_1|MBX_0;
4465fcf3ce44SJohn Forte mcp->timeout = MAILBOX_TOV;
4466fcf3ce44SJohn Forte rval = ql_mailbox_command(ha, mcp);
4467fcf3ce44SJohn Forte
4468fcf3ce44SJohn Forte /* Return mailbox data. */
4469fcf3ce44SJohn Forte if (mr != NULL) {
4470fcf3ce44SJohn Forte mr->mb[0] = mcp->mb[0];
4471fcf3ce44SJohn Forte mr->mb[1] = mcp->mb[1];
4472fcf3ce44SJohn Forte }
4473fcf3ce44SJohn Forte
4474fcf3ce44SJohn Forte if (rval != QL_SUCCESS) {
4475fcf3ce44SJohn Forte EL(ha, "failed=%xh\n", rval);
4476fcf3ce44SJohn Forte } else {
4477fcf3ce44SJohn Forte /*EMPTY*/
4478*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4479fcf3ce44SJohn Forte }
4480fcf3ce44SJohn Forte
4481fcf3ce44SJohn Forte return (rval);
4482fcf3ce44SJohn Forte }
44835dfd244aSDaniel Beauregard
44845dfd244aSDaniel Beauregard /*
44855dfd244aSDaniel Beauregard * ql_restart_mpi
44865dfd244aSDaniel Beauregard * The Restart MPI Firmware Mailbox Command will reset the MPI RISC,
44875dfd244aSDaniel Beauregard * reload MPI firmware from Flash, and execute the firmware.
44885dfd244aSDaniel Beauregard *
44895dfd244aSDaniel Beauregard * Input:
44905dfd244aSDaniel Beauregard * ha: adapter state pointer.
44915dfd244aSDaniel Beauregard *
44925dfd244aSDaniel Beauregard * Returns:
44935dfd244aSDaniel Beauregard * ql local function return status code.
44945dfd244aSDaniel Beauregard *
44955dfd244aSDaniel Beauregard * Context:
44965dfd244aSDaniel Beauregard * Kernel context.
44975dfd244aSDaniel Beauregard */
44985dfd244aSDaniel Beauregard int
ql_restart_mpi(ql_adapter_state_t * ha)44995dfd244aSDaniel Beauregard ql_restart_mpi(ql_adapter_state_t *ha)
45005dfd244aSDaniel Beauregard {
45015dfd244aSDaniel Beauregard int rval;
45025dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
45035dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
45045dfd244aSDaniel Beauregard
4505*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
45065dfd244aSDaniel Beauregard
45075dfd244aSDaniel Beauregard mcp->mb[0] = MBC_RESTART_MPI;
45085dfd244aSDaniel Beauregard mcp->out_mb = MBX_0;
45095dfd244aSDaniel Beauregard mcp->in_mb = MBX_1|MBX_0;
45105dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
45115dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
45125dfd244aSDaniel Beauregard
45135dfd244aSDaniel Beauregard /* Return mailbox data. */
45145dfd244aSDaniel Beauregard if (rval != QL_SUCCESS) {
45155dfd244aSDaniel Beauregard EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
45165dfd244aSDaniel Beauregard } else {
45175dfd244aSDaniel Beauregard /*EMPTY*/
4518*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
45195dfd244aSDaniel Beauregard }
45205dfd244aSDaniel Beauregard
45215dfd244aSDaniel Beauregard return (rval);
45225dfd244aSDaniel Beauregard }
45235dfd244aSDaniel Beauregard
45245dfd244aSDaniel Beauregard /*
45255dfd244aSDaniel Beauregard * ql_idc_request
45265dfd244aSDaniel Beauregard * Inter-Driver Communication Request.
45275dfd244aSDaniel Beauregard *
45285dfd244aSDaniel Beauregard * Input:
45295dfd244aSDaniel Beauregard * ha: adapter state pointer.
45305dfd244aSDaniel Beauregard * mr: pointer for mailbox data.
45315dfd244aSDaniel Beauregard *
45325dfd244aSDaniel Beauregard * Returns:
45335dfd244aSDaniel Beauregard * ql local function return status code.
45345dfd244aSDaniel Beauregard *
45355dfd244aSDaniel Beauregard * Context:
45365dfd244aSDaniel Beauregard * Kernel context.
45375dfd244aSDaniel Beauregard */
45385dfd244aSDaniel Beauregard int
ql_idc_request(ql_adapter_state_t * ha,ql_mbx_data_t * mr)45395dfd244aSDaniel Beauregard ql_idc_request(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
45405dfd244aSDaniel Beauregard {
45415dfd244aSDaniel Beauregard int rval;
45425dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
45435dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
45445dfd244aSDaniel Beauregard
4545*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
45465dfd244aSDaniel Beauregard
45475dfd244aSDaniel Beauregard mcp->mb[0] = MBC_IDC_REQUEST;
45485dfd244aSDaniel Beauregard mcp->mb[1] = mr->mb[1];
45495dfd244aSDaniel Beauregard mcp->mb[2] = mr->mb[2];
45505dfd244aSDaniel Beauregard mcp->mb[3] = mr->mb[3];
45515dfd244aSDaniel Beauregard mcp->mb[4] = mr->mb[4];
45525dfd244aSDaniel Beauregard mcp->mb[5] = mr->mb[5];
45535dfd244aSDaniel Beauregard mcp->mb[6] = mr->mb[6];
45545dfd244aSDaniel Beauregard mcp->mb[7] = mr->mb[7];
45555dfd244aSDaniel Beauregard mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
45565dfd244aSDaniel Beauregard mcp->in_mb = MBX_2|MBX_0;
45575dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
45585dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
45595dfd244aSDaniel Beauregard
45605dfd244aSDaniel Beauregard if (rval == QL_SUCCESS) {
4561*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
4562*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
45635dfd244aSDaniel Beauregard } else {
45645dfd244aSDaniel Beauregard EL(ha, "status=%xh, mbx2=%xh\n", rval, mcp->mb[2]);
45655dfd244aSDaniel Beauregard }
45665dfd244aSDaniel Beauregard
45675dfd244aSDaniel Beauregard return (rval);
45685dfd244aSDaniel Beauregard }
45695dfd244aSDaniel Beauregard
45705dfd244aSDaniel Beauregard /*
45715dfd244aSDaniel Beauregard * ql_idc_ack
45725dfd244aSDaniel Beauregard * Inter-Driver Communication Acknowledgement.
45735dfd244aSDaniel Beauregard *
45745dfd244aSDaniel Beauregard * Input:
45755dfd244aSDaniel Beauregard * ha: adapter state pointer.
45765dfd244aSDaniel Beauregard *
45775dfd244aSDaniel Beauregard * Returns:
45785dfd244aSDaniel Beauregard * ql local function return status code.
45795dfd244aSDaniel Beauregard *
45805dfd244aSDaniel Beauregard * Context:
45815dfd244aSDaniel Beauregard * Kernel context.
45825dfd244aSDaniel Beauregard */
45835dfd244aSDaniel Beauregard int
ql_idc_ack(ql_adapter_state_t * ha)45845dfd244aSDaniel Beauregard ql_idc_ack(ql_adapter_state_t *ha)
45855dfd244aSDaniel Beauregard {
45865dfd244aSDaniel Beauregard int rval;
45875dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
45885dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
45895dfd244aSDaniel Beauregard
4590*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
45915dfd244aSDaniel Beauregard
45925dfd244aSDaniel Beauregard mcp->mb[0] = MBC_IDC_ACK;
45935dfd244aSDaniel Beauregard mcp->mb[1] = ha->idc_mb[1];
45945dfd244aSDaniel Beauregard mcp->mb[2] = ha->idc_mb[2];
45955dfd244aSDaniel Beauregard mcp->mb[3] = ha->idc_mb[3];
45965dfd244aSDaniel Beauregard mcp->mb[4] = ha->idc_mb[4];
45975dfd244aSDaniel Beauregard mcp->mb[5] = ha->idc_mb[5];
45985dfd244aSDaniel Beauregard mcp->mb[6] = ha->idc_mb[6];
45995dfd244aSDaniel Beauregard mcp->mb[7] = ha->idc_mb[7];
46005dfd244aSDaniel Beauregard mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
46015dfd244aSDaniel Beauregard mcp->in_mb = MBX_0;
46025dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
46035dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
46045dfd244aSDaniel Beauregard
4605*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
46065dfd244aSDaniel Beauregard
46075dfd244aSDaniel Beauregard return (rval);
46085dfd244aSDaniel Beauregard }
46095dfd244aSDaniel Beauregard
46105dfd244aSDaniel Beauregard /*
46115dfd244aSDaniel Beauregard * ql_idc_time_extend
46125dfd244aSDaniel Beauregard * Inter-Driver Communication Time Extend
46135dfd244aSDaniel Beauregard *
46145dfd244aSDaniel Beauregard * Input:
46155dfd244aSDaniel Beauregard * ha: adapter state pointer.
46165dfd244aSDaniel Beauregard *
46175dfd244aSDaniel Beauregard * Returns:
46185dfd244aSDaniel Beauregard * ql local function return status code.
46195dfd244aSDaniel Beauregard *
46205dfd244aSDaniel Beauregard * Context:
46215dfd244aSDaniel Beauregard * Kernel context.
46225dfd244aSDaniel Beauregard */
46235dfd244aSDaniel Beauregard int
ql_idc_time_extend(ql_adapter_state_t * ha)4624*4c3888b8SHans Rosenfeld ql_idc_time_extend(ql_adapter_state_t *ha)
46255dfd244aSDaniel Beauregard {
46265dfd244aSDaniel Beauregard int rval;
46275dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
46285dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
46295dfd244aSDaniel Beauregard
4630*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
46315dfd244aSDaniel Beauregard
46325dfd244aSDaniel Beauregard mcp->mb[0] = MBC_IDC_TIME_EXTEND;
4633*4c3888b8SHans Rosenfeld mcp->mb[1] = ha->idc_mb[1];
4634*4c3888b8SHans Rosenfeld mcp->mb[2] = ha->idc_mb[2];
4635*4c3888b8SHans Rosenfeld mcp->mb[3] = ha->idc_mb[3];
4636*4c3888b8SHans Rosenfeld mcp->mb[4] = ha->idc_mb[4];
4637*4c3888b8SHans Rosenfeld mcp->mb[5] = ha->idc_mb[5];
4638*4c3888b8SHans Rosenfeld mcp->mb[6] = ha->idc_mb[6];
4639*4c3888b8SHans Rosenfeld mcp->mb[7] = ha->idc_mb[7];
4640*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
46415dfd244aSDaniel Beauregard mcp->in_mb = MBX_0;
46425dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
46435dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
46445dfd244aSDaniel Beauregard
4645*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
46465dfd244aSDaniel Beauregard
46475dfd244aSDaniel Beauregard return (rval);
46485dfd244aSDaniel Beauregard }
46495dfd244aSDaniel Beauregard
46504f8b8adcSDaniel Beauregard /*
46514f8b8adcSDaniel Beauregard * ql_port_reset
4652eb82ff87SDaniel Beauregard * The Port Reset for the external 10G port associated with this function.
46534f8b8adcSDaniel Beauregard *
46544f8b8adcSDaniel Beauregard * Input:
46554f8b8adcSDaniel Beauregard * ha: adapter state pointer.
46564f8b8adcSDaniel Beauregard *
46574f8b8adcSDaniel Beauregard * Returns:
46584f8b8adcSDaniel Beauregard * ql local function return status code.
46594f8b8adcSDaniel Beauregard *
46604f8b8adcSDaniel Beauregard * Context:
46614f8b8adcSDaniel Beauregard * Kernel context.
46624f8b8adcSDaniel Beauregard */
46634f8b8adcSDaniel Beauregard int
ql_port_reset(ql_adapter_state_t * ha)46644f8b8adcSDaniel Beauregard ql_port_reset(ql_adapter_state_t *ha)
46654f8b8adcSDaniel Beauregard {
46664f8b8adcSDaniel Beauregard int rval;
46674f8b8adcSDaniel Beauregard mbx_cmd_t mc = {0};
46684f8b8adcSDaniel Beauregard mbx_cmd_t *mcp = &mc;
46694f8b8adcSDaniel Beauregard
4670*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
46714f8b8adcSDaniel Beauregard
46724f8b8adcSDaniel Beauregard mcp->mb[0] = MBC_PORT_RESET;
46734f8b8adcSDaniel Beauregard mcp->out_mb = MBX_0;
46744f8b8adcSDaniel Beauregard mcp->in_mb = MBX_0;
46754f8b8adcSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
46764f8b8adcSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
46774f8b8adcSDaniel Beauregard
4678*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
46794f8b8adcSDaniel Beauregard
46804f8b8adcSDaniel Beauregard return (rval);
46814f8b8adcSDaniel Beauregard }
46824f8b8adcSDaniel Beauregard
46835dfd244aSDaniel Beauregard /*
46845dfd244aSDaniel Beauregard * ql_set_port_config
46855dfd244aSDaniel Beauregard * The Set Port Configuration command sets the configuration for the
4686eb82ff87SDaniel Beauregard * external 10G port associated with this function.
46875dfd244aSDaniel Beauregard *
46885dfd244aSDaniel Beauregard * Input:
46895dfd244aSDaniel Beauregard * ha: adapter state pointer.
46905dfd244aSDaniel Beauregard * mr: pointer for mailbox data.
46915dfd244aSDaniel Beauregard *
46925dfd244aSDaniel Beauregard * Returns:
46935dfd244aSDaniel Beauregard * ql local function return status code.
46945dfd244aSDaniel Beauregard *
46955dfd244aSDaniel Beauregard * Context:
46965dfd244aSDaniel Beauregard * Kernel context.
46975dfd244aSDaniel Beauregard */
46985dfd244aSDaniel Beauregard int
ql_set_port_config(ql_adapter_state_t * ha,ql_mbx_data_t * mrp)4699eb82ff87SDaniel Beauregard ql_set_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
47005dfd244aSDaniel Beauregard {
47015dfd244aSDaniel Beauregard int rval;
47025dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
47035dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
47045dfd244aSDaniel Beauregard
4705*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
47065dfd244aSDaniel Beauregard
47075dfd244aSDaniel Beauregard mcp->mb[0] = MBC_SET_PORT_CONFIG;
4708eb82ff87SDaniel Beauregard mcp->mb[1] = mrp->mb[1];
4709eb82ff87SDaniel Beauregard mcp->mb[2] = mrp->mb[2];
4710eb82ff87SDaniel Beauregard mcp->mb[3] = mrp->mb[3];
4711eb82ff87SDaniel Beauregard mcp->mb[4] = mrp->mb[4];
47124f8b8adcSDaniel Beauregard mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
47135dfd244aSDaniel Beauregard mcp->in_mb = MBX_0;
47145dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
47155dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
47165dfd244aSDaniel Beauregard
4717*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
47185dfd244aSDaniel Beauregard
47195dfd244aSDaniel Beauregard return (rval);
47205dfd244aSDaniel Beauregard }
47215dfd244aSDaniel Beauregard
47225dfd244aSDaniel Beauregard /*
47235dfd244aSDaniel Beauregard * ql_get_port_config
47245dfd244aSDaniel Beauregard * The Get Port Configuration command retrieves the current configuration
4725eb82ff87SDaniel Beauregard * for the external 10G port associated with this function.
47265dfd244aSDaniel Beauregard *
47275dfd244aSDaniel Beauregard * Input:
47285dfd244aSDaniel Beauregard * ha: adapter state pointer.
47295dfd244aSDaniel Beauregard * mr: pointer for mailbox data.
47305dfd244aSDaniel Beauregard *
47315dfd244aSDaniel Beauregard * Returns:
47325dfd244aSDaniel Beauregard * ql local function return status code.
47335dfd244aSDaniel Beauregard *
47345dfd244aSDaniel Beauregard * Context:
47355dfd244aSDaniel Beauregard * Kernel context.
47365dfd244aSDaniel Beauregard */
47375dfd244aSDaniel Beauregard int
ql_get_port_config(ql_adapter_state_t * ha,ql_mbx_data_t * mrp)4738eb82ff87SDaniel Beauregard ql_get_port_config(ql_adapter_state_t *ha, ql_mbx_data_t *mrp)
47395dfd244aSDaniel Beauregard {
47405dfd244aSDaniel Beauregard int rval;
47415dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
47425dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
47435dfd244aSDaniel Beauregard
4744*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
47455dfd244aSDaniel Beauregard
47465dfd244aSDaniel Beauregard mcp->mb[0] = MBC_GET_PORT_CONFIG;
47475dfd244aSDaniel Beauregard mcp->out_mb = MBX_0;
47484f8b8adcSDaniel Beauregard mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
47495dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
47505dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
47515dfd244aSDaniel Beauregard
47525dfd244aSDaniel Beauregard if (rval == QL_SUCCESS) {
4753eb82ff87SDaniel Beauregard if (mrp != NULL) {
4754eb82ff87SDaniel Beauregard mrp->mb[1] = mcp->mb[1];
4755eb82ff87SDaniel Beauregard mrp->mb[2] = mcp->mb[2];
4756eb82ff87SDaniel Beauregard mrp->mb[3] = mcp->mb[3];
4757eb82ff87SDaniel Beauregard mrp->mb[4] = mcp->mb[4];
47585dfd244aSDaniel Beauregard }
4759*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
47605dfd244aSDaniel Beauregard } else {
47614f8b8adcSDaniel Beauregard EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, mbx4=%xh\n",
47624f8b8adcSDaniel Beauregard rval, mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[4]);
47635dfd244aSDaniel Beauregard }
47645dfd244aSDaniel Beauregard
47655dfd244aSDaniel Beauregard return (rval);
47665dfd244aSDaniel Beauregard }
47675dfd244aSDaniel Beauregard
47685dfd244aSDaniel Beauregard /*
47695dfd244aSDaniel Beauregard * ql_flash_access
47705dfd244aSDaniel Beauregard * The Get Port Configuration command retrieves the current configuration
4771f885d00fSDaniel Beauregard * for the external 10G port associated with this function
47725dfd244aSDaniel Beauregard *
47735dfd244aSDaniel Beauregard * Input:
47745dfd244aSDaniel Beauregard * ha: adapter state pointer.
47755dfd244aSDaniel Beauregard * cmd: command.
47765dfd244aSDaniel Beauregard * start: 32bit word address.
47775dfd244aSDaniel Beauregard * end: 32bit word address.
47785dfd244aSDaniel Beauregard * dp: 32bit word pointer.
47795dfd244aSDaniel Beauregard *
47805dfd244aSDaniel Beauregard * Returns:
47815dfd244aSDaniel Beauregard * ql local function return status code.
47825dfd244aSDaniel Beauregard *
47835dfd244aSDaniel Beauregard * Context:
47845dfd244aSDaniel Beauregard * Kernel context.
47855dfd244aSDaniel Beauregard */
47865dfd244aSDaniel Beauregard int
ql_flash_access(ql_adapter_state_t * ha,uint16_t cmd,uint32_t start,uint32_t end,uint32_t * dp)47875dfd244aSDaniel Beauregard ql_flash_access(ql_adapter_state_t *ha, uint16_t cmd, uint32_t start,
47885dfd244aSDaniel Beauregard uint32_t end, uint32_t *dp)
47895dfd244aSDaniel Beauregard {
47905dfd244aSDaniel Beauregard int rval;
47915dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
47925dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
47935dfd244aSDaniel Beauregard
4794*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, cmd=%xh\n", cmd);
47955dfd244aSDaniel Beauregard
47965dfd244aSDaniel Beauregard mcp->mb[0] = MBC_FLASH_ACCESS;
4797*4c3888b8SHans Rosenfeld mcp->mb[1] = cmd;
47985dfd244aSDaniel Beauregard mcp->mb[2] = LSW(start);
47995dfd244aSDaniel Beauregard mcp->mb[3] = MSW(start);
48005dfd244aSDaniel Beauregard mcp->mb[4] = LSW(end);
48015dfd244aSDaniel Beauregard mcp->mb[5] = MSW(end);
48025dfd244aSDaniel Beauregard
48035dfd244aSDaniel Beauregard mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4804*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_4;
48055dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
48065dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
48075dfd244aSDaniel Beauregard
48085dfd244aSDaniel Beauregard if (rval != QL_SUCCESS) {
4809*4c3888b8SHans Rosenfeld EL(ha, "cmd=%xh, status=%xh, mbx1=%xh, mbx2=%xh, mbx3=%xh, "
4810*4c3888b8SHans Rosenfeld "mbx4=%xh\n", cmd, rval, mcp->mb[1], mcp->mb[2],
4811*4c3888b8SHans Rosenfeld mcp->mb[3], mcp->mb[4]);
48125dfd244aSDaniel Beauregard } else {
48135dfd244aSDaniel Beauregard if (dp != NULL) {
48145dfd244aSDaniel Beauregard *dp = (uint32_t)mcp->mb[1];
48155dfd244aSDaniel Beauregard }
4816*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
48175dfd244aSDaniel Beauregard }
48185dfd244aSDaniel Beauregard
48195dfd244aSDaniel Beauregard return (rval);
48205dfd244aSDaniel Beauregard }
48215dfd244aSDaniel Beauregard
48225dfd244aSDaniel Beauregard /*
48235dfd244aSDaniel Beauregard * ql_get_xgmac_stats
48245dfd244aSDaniel Beauregard * Issue et XGMAC Statistics Mailbox command
48255dfd244aSDaniel Beauregard *
48265dfd244aSDaniel Beauregard * Input:
48275dfd244aSDaniel Beauregard * ha: adapter state pointer.
48285dfd244aSDaniel Beauregard * size: size of data buffer.
48295dfd244aSDaniel Beauregard * bufp: data pointer for DMA data.
48305dfd244aSDaniel Beauregard *
48315dfd244aSDaniel Beauregard * Returns:
48325dfd244aSDaniel Beauregard * ql local function return status code.
48335dfd244aSDaniel Beauregard *
48345dfd244aSDaniel Beauregard * Context:
48355dfd244aSDaniel Beauregard * Kernel context.
48365dfd244aSDaniel Beauregard */
48375dfd244aSDaniel Beauregard int
ql_get_xgmac_stats(ql_adapter_state_t * ha,size_t size,caddr_t bufp)48385dfd244aSDaniel Beauregard ql_get_xgmac_stats(ql_adapter_state_t *ha, size_t size, caddr_t bufp)
48395dfd244aSDaniel Beauregard {
48405dfd244aSDaniel Beauregard int rval;
48415dfd244aSDaniel Beauregard dma_mem_t mem_desc;
48425dfd244aSDaniel Beauregard mbx_cmd_t mc = {0};
48435dfd244aSDaniel Beauregard mbx_cmd_t *mcp = &mc;
48445dfd244aSDaniel Beauregard
4845*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
48465dfd244aSDaniel Beauregard
48475dfd244aSDaniel Beauregard if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
48485dfd244aSDaniel Beauregard (uint32_t)size)) != QL_SUCCESS) {
48495dfd244aSDaniel Beauregard EL(ha, "setup_mbox_dma_resources failed: %xh\n", rval);
48505dfd244aSDaniel Beauregard return (QL_MEMORY_ALLOC_FAILED);
48515dfd244aSDaniel Beauregard }
48525dfd244aSDaniel Beauregard
48535dfd244aSDaniel Beauregard mcp->mb[0] = MBC_GET_XGMAC_STATS;
48545dfd244aSDaniel Beauregard mcp->mb[2] = MSW(mem_desc.cookie.dmac_address);
48555dfd244aSDaniel Beauregard mcp->mb[3] = LSW(mem_desc.cookie.dmac_address);
48565dfd244aSDaniel Beauregard mcp->mb[6] = MSW(mem_desc.cookie.dmac_notused);
48575dfd244aSDaniel Beauregard mcp->mb[7] = LSW(mem_desc.cookie.dmac_notused);
48585dfd244aSDaniel Beauregard mcp->mb[8] = (uint16_t)(size >> 2);
48595dfd244aSDaniel Beauregard mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
48605dfd244aSDaniel Beauregard mcp->in_mb = MBX_2|MBX_1|MBX_0;
48615dfd244aSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
48625dfd244aSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
48635dfd244aSDaniel Beauregard
48645dfd244aSDaniel Beauregard if (rval == QL_SUCCESS) {
48655dfd244aSDaniel Beauregard ql_get_mbox_dma_data(&mem_desc, bufp);
48665dfd244aSDaniel Beauregard }
48675dfd244aSDaniel Beauregard ql_free_dma_resource(ha, &mem_desc);
48685dfd244aSDaniel Beauregard
48695dfd244aSDaniel Beauregard if (rval != QL_SUCCESS) {
48705dfd244aSDaniel Beauregard EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
48715dfd244aSDaniel Beauregard mcp->mb[2]);
48725dfd244aSDaniel Beauregard } else {
48735dfd244aSDaniel Beauregard /*EMPTY*/
4874*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
48755dfd244aSDaniel Beauregard }
48765dfd244aSDaniel Beauregard
48775dfd244aSDaniel Beauregard return (rval);
48785dfd244aSDaniel Beauregard }
48794f8b8adcSDaniel Beauregard
48804f8b8adcSDaniel Beauregard /*
48814f8b8adcSDaniel Beauregard * ql_get_dcbx_params
48824f8b8adcSDaniel Beauregard * Issue get DCBX parameters mailbox command.
48834f8b8adcSDaniel Beauregard *
48844f8b8adcSDaniel Beauregard * Input:
48854f8b8adcSDaniel Beauregard * ha: adapter state pointer.
48864f8b8adcSDaniel Beauregard * size: size of data buffer.
48874f8b8adcSDaniel Beauregard * bufp: data pointer for DMA data.
48884f8b8adcSDaniel Beauregard *
48894f8b8adcSDaniel Beauregard * Returns:
48904f8b8adcSDaniel Beauregard * ql local function return status code.
48914f8b8adcSDaniel Beauregard *
48924f8b8adcSDaniel Beauregard * Context:
48934f8b8adcSDaniel Beauregard * Kernel context.
48944f8b8adcSDaniel Beauregard */
48954f8b8adcSDaniel Beauregard int
ql_get_dcbx_params(ql_adapter_state_t * ha,uint32_t size,caddr_t bufp)48964f8b8adcSDaniel Beauregard ql_get_dcbx_params(ql_adapter_state_t *ha, uint32_t size, caddr_t bufp)
48974f8b8adcSDaniel Beauregard {
48984f8b8adcSDaniel Beauregard int rval;
48994f8b8adcSDaniel Beauregard dma_mem_t mem_desc;
49004f8b8adcSDaniel Beauregard mbx_cmd_t mc = {0};
49014f8b8adcSDaniel Beauregard mbx_cmd_t *mcp = &mc;
49024f8b8adcSDaniel Beauregard
4903*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
49044f8b8adcSDaniel Beauregard
49054f8b8adcSDaniel Beauregard if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc, size)) !=
49064f8b8adcSDaniel Beauregard QL_SUCCESS) {
49074f8b8adcSDaniel Beauregard EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
49084f8b8adcSDaniel Beauregard return (QL_MEMORY_ALLOC_FAILED);
49094f8b8adcSDaniel Beauregard }
49104f8b8adcSDaniel Beauregard
49114f8b8adcSDaniel Beauregard mcp->mb[0] = MBC_GET_DCBX_PARAMS;
49124f8b8adcSDaniel Beauregard mcp->mb[1] = 0; /* Return all DCBX paramters */
49134f8b8adcSDaniel Beauregard mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
49144f8b8adcSDaniel Beauregard mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
49154f8b8adcSDaniel Beauregard mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
49164f8b8adcSDaniel Beauregard mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
49174f8b8adcSDaniel Beauregard mcp->mb[8] = (uint16_t)size;
49184f8b8adcSDaniel Beauregard mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
49194f8b8adcSDaniel Beauregard mcp->in_mb = MBX_2|MBX_1|MBX_0;
49204f8b8adcSDaniel Beauregard mcp->timeout = MAILBOX_TOV;
49214f8b8adcSDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
49224f8b8adcSDaniel Beauregard
49234f8b8adcSDaniel Beauregard if (rval == QL_SUCCESS) {
49244f8b8adcSDaniel Beauregard ql_get_mbox_dma_data(&mem_desc, bufp);
49254f8b8adcSDaniel Beauregard }
49264f8b8adcSDaniel Beauregard
49274f8b8adcSDaniel Beauregard ql_free_dma_resource(ha, &mem_desc);
49284f8b8adcSDaniel Beauregard
49294f8b8adcSDaniel Beauregard if (rval != QL_SUCCESS) {
49304f8b8adcSDaniel Beauregard EL(ha, "failed=%xh\n", rval);
49314f8b8adcSDaniel Beauregard } else {
49324f8b8adcSDaniel Beauregard /*EMPTY*/
4933*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
49344f8b8adcSDaniel Beauregard }
49354f8b8adcSDaniel Beauregard
49364f8b8adcSDaniel Beauregard return (rval);
49374f8b8adcSDaniel Beauregard }
4938eb82ff87SDaniel Beauregard /*
4939eb82ff87SDaniel Beauregard * ql_get_fcf_list
4940eb82ff87SDaniel Beauregard * Issue get FCF list mailbox command.
4941eb82ff87SDaniel Beauregard *
4942eb82ff87SDaniel Beauregard * Input:
4943eb82ff87SDaniel Beauregard * ha: adapter state pointer.
4944eb82ff87SDaniel Beauregard * fcf_list: pointer to ql_fcf_list_desc_t
4945eb82ff87SDaniel Beauregard * bufp: data pointer for DMA data.
4946eb82ff87SDaniel Beauregard *
4947eb82ff87SDaniel Beauregard * Returns:
4948eb82ff87SDaniel Beauregard * ql local function return status code.
4949eb82ff87SDaniel Beauregard *
4950eb82ff87SDaniel Beauregard * Context:
4951eb82ff87SDaniel Beauregard * Kernel context.
4952eb82ff87SDaniel Beauregard */
4953eb82ff87SDaniel Beauregard
4954eb82ff87SDaniel Beauregard int
ql_get_fcf_list_mbx(ql_adapter_state_t * ha,ql_fcf_list_desc_t * fcf_list,caddr_t bufp)4955eb82ff87SDaniel Beauregard ql_get_fcf_list_mbx(ql_adapter_state_t *ha, ql_fcf_list_desc_t *fcf_list,
4956eb82ff87SDaniel Beauregard caddr_t bufp)
4957eb82ff87SDaniel Beauregard {
4958eb82ff87SDaniel Beauregard int rval;
4959eb82ff87SDaniel Beauregard dma_mem_t mem_desc;
4960eb82ff87SDaniel Beauregard mbx_cmd_t mc = {0};
4961eb82ff87SDaniel Beauregard mbx_cmd_t *mcp = &mc;
4962eb82ff87SDaniel Beauregard
4963*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
4964eb82ff87SDaniel Beauregard
4965eb82ff87SDaniel Beauregard if ((rval = ql_setup_mbox_dma_resources(ha, &mem_desc,
4966eb82ff87SDaniel Beauregard fcf_list->buffer_size)) !=
4967eb82ff87SDaniel Beauregard QL_SUCCESS) {
4968eb82ff87SDaniel Beauregard EL(ha, "failed=%xh\n", QL_MEMORY_ALLOC_FAILED);
4969eb82ff87SDaniel Beauregard return (QL_MEMORY_ALLOC_FAILED);
4970eb82ff87SDaniel Beauregard }
4971eb82ff87SDaniel Beauregard
4972eb82ff87SDaniel Beauregard mcp->mb[0] = MBC_GET_FCF_LIST;
4973eb82ff87SDaniel Beauregard mcp->mb[1] = fcf_list->options;
4974eb82ff87SDaniel Beauregard mcp->mb[2] = MSW(LSD(mem_desc.cookie.dmac_laddress));
4975eb82ff87SDaniel Beauregard mcp->mb[3] = LSW(LSD(mem_desc.cookie.dmac_laddress));
4976eb82ff87SDaniel Beauregard mcp->mb[6] = MSW(MSD(mem_desc.cookie.dmac_laddress));
4977eb82ff87SDaniel Beauregard mcp->mb[7] = LSW(MSD(mem_desc.cookie.dmac_laddress));
4978eb82ff87SDaniel Beauregard mcp->mb[8] = (uint16_t)fcf_list->buffer_size;
4979eb82ff87SDaniel Beauregard mcp->mb[9] = fcf_list->fcf_index;
4980eb82ff87SDaniel Beauregard mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4981eb82ff87SDaniel Beauregard mcp->in_mb = MBX_2|MBX_1|MBX_0;
4982eb82ff87SDaniel Beauregard mcp->timeout = MAILBOX_TOV;
4983eb82ff87SDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
4984eb82ff87SDaniel Beauregard
4985eb82ff87SDaniel Beauregard if (rval == QL_SUCCESS) {
4986eb82ff87SDaniel Beauregard ql_get_mbox_dma_data(&mem_desc, bufp);
4987eb82ff87SDaniel Beauregard fcf_list->buffer_size = (uint16_t)mcp->mb[1];
4988eb82ff87SDaniel Beauregard }
4989eb82ff87SDaniel Beauregard
4990eb82ff87SDaniel Beauregard ql_free_dma_resource(ha, &mem_desc);
4991eb82ff87SDaniel Beauregard
4992eb82ff87SDaniel Beauregard if (rval != QL_SUCCESS) {
4993eb82ff87SDaniel Beauregard EL(ha, "status=%xh, mbx1=%xh, mbx2=%xh\n", rval, mcp->mb[1],
4994eb82ff87SDaniel Beauregard mcp->mb[2]);
4995eb82ff87SDaniel Beauregard } else {
4996eb82ff87SDaniel Beauregard /*EMPTY*/
4997*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
4998eb82ff87SDaniel Beauregard }
4999eb82ff87SDaniel Beauregard
5000eb82ff87SDaniel Beauregard return (rval);
5001eb82ff87SDaniel Beauregard }
5002eb82ff87SDaniel Beauregard
5003eb82ff87SDaniel Beauregard /*
5004eb82ff87SDaniel Beauregard * ql_get_resource_cnts
5005eb82ff87SDaniel Beauregard * Issue get Resourse Count mailbox command.
5006eb82ff87SDaniel Beauregard *
5007eb82ff87SDaniel Beauregard * Input:
5008eb82ff87SDaniel Beauregard * ha: adapter state pointer.
5009eb82ff87SDaniel Beauregard * mr: pointer for mailbox data.
5010eb82ff87SDaniel Beauregard *
5011eb82ff87SDaniel Beauregard * Returns:
5012eb82ff87SDaniel Beauregard * ql local function return status code.
5013eb82ff87SDaniel Beauregard *
5014eb82ff87SDaniel Beauregard * Context:
5015eb82ff87SDaniel Beauregard * Kernel context.
5016eb82ff87SDaniel Beauregard */
5017eb82ff87SDaniel Beauregard
5018eb82ff87SDaniel Beauregard int
ql_get_resource_cnts(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5019eb82ff87SDaniel Beauregard ql_get_resource_cnts(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5020eb82ff87SDaniel Beauregard {
5021eb82ff87SDaniel Beauregard int rval;
5022eb82ff87SDaniel Beauregard mbx_cmd_t mc = {0};
5023eb82ff87SDaniel Beauregard mbx_cmd_t *mcp = &mc;
5024eb82ff87SDaniel Beauregard
5025*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5026eb82ff87SDaniel Beauregard
5027eb82ff87SDaniel Beauregard mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
5028*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_9|MBX_1|MBX_0;
5029eb82ff87SDaniel Beauregard mcp->in_mb = MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|
5030eb82ff87SDaniel Beauregard MBX_3|MBX_2|MBX_1|MBX_0;
5031eb82ff87SDaniel Beauregard mcp->timeout = MAILBOX_TOV;
5032eb82ff87SDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
5033eb82ff87SDaniel Beauregard
5034eb82ff87SDaniel Beauregard /* Return mailbox data. */
5035eb82ff87SDaniel Beauregard if (mr != NULL) {
5036eb82ff87SDaniel Beauregard mr->mb[1] = mcp->mb[1];
5037eb82ff87SDaniel Beauregard mr->mb[2] = mcp->mb[2];
5038eb82ff87SDaniel Beauregard mr->mb[3] = mcp->mb[3];
5039eb82ff87SDaniel Beauregard mr->mb[6] = mcp->mb[6];
5040eb82ff87SDaniel Beauregard mr->mb[7] = mcp->mb[7];
5041eb82ff87SDaniel Beauregard mr->mb[10] = mcp->mb[10];
5042eb82ff87SDaniel Beauregard mr->mb[11] = mcp->mb[11];
5043eb82ff87SDaniel Beauregard mr->mb[12] = mcp->mb[12];
5044eb82ff87SDaniel Beauregard }
5045eb82ff87SDaniel Beauregard
5046eb82ff87SDaniel Beauregard if (rval != QL_SUCCESS) {
5047eb82ff87SDaniel Beauregard EL(ha, "failed=%xh\n", rval);
5048eb82ff87SDaniel Beauregard } else {
5049eb82ff87SDaniel Beauregard /*EMPTY*/
5050*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5051eb82ff87SDaniel Beauregard }
5052eb82ff87SDaniel Beauregard
5053eb82ff87SDaniel Beauregard return (rval);
5054eb82ff87SDaniel Beauregard }
5055eb82ff87SDaniel Beauregard
5056eb82ff87SDaniel Beauregard /*
5057eb82ff87SDaniel Beauregard * ql_toggle_interrupt
5058eb82ff87SDaniel Beauregard * Issue Toggle Interrupt Mailbox Command.
5059eb82ff87SDaniel Beauregard *
5060eb82ff87SDaniel Beauregard * Input:
5061eb82ff87SDaniel Beauregard * ha: adapter state pointer.
5062eb82ff87SDaniel Beauregard * opt: 0 = disable, 1 = enable.
5063eb82ff87SDaniel Beauregard *
5064eb82ff87SDaniel Beauregard * Returns:
5065eb82ff87SDaniel Beauregard * ql local function return status code.
5066eb82ff87SDaniel Beauregard *
5067eb82ff87SDaniel Beauregard * Context:
5068eb82ff87SDaniel Beauregard * Kernel context.
5069eb82ff87SDaniel Beauregard */
5070eb82ff87SDaniel Beauregard int
ql_toggle_interrupt(ql_adapter_state_t * ha,uint16_t opt)5071eb82ff87SDaniel Beauregard ql_toggle_interrupt(ql_adapter_state_t *ha, uint16_t opt)
5072eb82ff87SDaniel Beauregard {
5073eb82ff87SDaniel Beauregard int rval;
5074eb82ff87SDaniel Beauregard mbx_cmd_t mc = {0};
5075eb82ff87SDaniel Beauregard mbx_cmd_t *mcp = &mc;
5076eb82ff87SDaniel Beauregard
5077*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5078eb82ff87SDaniel Beauregard
5079eb82ff87SDaniel Beauregard mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
5080eb82ff87SDaniel Beauregard mcp->mb[1] = opt;
5081eb82ff87SDaniel Beauregard mcp->out_mb = MBX_1|MBX_0;
5082eb82ff87SDaniel Beauregard mcp->in_mb = MBX_0;
5083f885d00fSDaniel Beauregard mcp->timeout = 2;
5084eb82ff87SDaniel Beauregard rval = ql_mailbox_command(ha, mcp);
5085eb82ff87SDaniel Beauregard
5086eb82ff87SDaniel Beauregard if (rval != QL_SUCCESS) {
5087eb82ff87SDaniel Beauregard EL(ha, "failed=%xh\n", rval);
5088eb82ff87SDaniel Beauregard } else {
5089eb82ff87SDaniel Beauregard /*EMPTY*/
5090*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5091*4c3888b8SHans Rosenfeld }
5092*4c3888b8SHans Rosenfeld
5093*4c3888b8SHans Rosenfeld return (rval);
5094*4c3888b8SHans Rosenfeld }
5095*4c3888b8SHans Rosenfeld
5096*4c3888b8SHans Rosenfeld /*
5097*4c3888b8SHans Rosenfeld * ql_get_md_template
5098*4c3888b8SHans Rosenfeld * Issue request mini-dump template Mailbox command
5099*4c3888b8SHans Rosenfeld *
5100*4c3888b8SHans Rosenfeld * Input:
5101*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5102*4c3888b8SHans Rosenfeld * mem: pointer to dma memory object for command.
5103*4c3888b8SHans Rosenfeld * mr: pointer for return mailboxes.
5104*4c3888b8SHans Rosenfeld * ofst: template offset.
5105*4c3888b8SHans Rosenfeld * opt: request command code.
5106*4c3888b8SHans Rosenfeld * GTO_TEMPLATE_SIZE = Request Template Size.
5107*4c3888b8SHans Rosenfeld * GTO_TEMPLATE = Request Template.
5108*4c3888b8SHans Rosenfeld *
5109*4c3888b8SHans Rosenfeld * Returns:
5110*4c3888b8SHans Rosenfeld * ql local function return status code.
5111*4c3888b8SHans Rosenfeld *
5112*4c3888b8SHans Rosenfeld * Context:
5113*4c3888b8SHans Rosenfeld * Kernel context.
5114*4c3888b8SHans Rosenfeld */
5115*4c3888b8SHans Rosenfeld int
ql_get_md_template(ql_adapter_state_t * ha,dma_mem_t * mem,ql_mbx_data_t * mr,uint32_t ofst,uint16_t opt)5116*4c3888b8SHans Rosenfeld ql_get_md_template(ql_adapter_state_t *ha, dma_mem_t *mem, ql_mbx_data_t *mr,
5117*4c3888b8SHans Rosenfeld uint32_t ofst, uint16_t opt)
5118*4c3888b8SHans Rosenfeld {
5119*4c3888b8SHans Rosenfeld int rval;
5120*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5121*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5122*4c3888b8SHans Rosenfeld
5123*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5124*4c3888b8SHans Rosenfeld
5125*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_GET_MD_TEMPLATE;
5126*4c3888b8SHans Rosenfeld mcp->mb[2] = opt;
5127*4c3888b8SHans Rosenfeld if (mem != NULL) {
5128*4c3888b8SHans Rosenfeld mcp->mb[4] = LSW(mem->cookies->dmac_address);
5129*4c3888b8SHans Rosenfeld mcp->mb[5] = MSW(mem->cookies->dmac_address);
5130*4c3888b8SHans Rosenfeld mcp->mb[6] = LSW(mem->cookies->dmac_notused);
5131*4c3888b8SHans Rosenfeld mcp->mb[7] = MSW(mem->cookies->dmac_notused);
5132*4c3888b8SHans Rosenfeld mcp->mb[8] = LSW(mem->size);
5133*4c3888b8SHans Rosenfeld mcp->mb[9] = MSW(mem->size);
5134*4c3888b8SHans Rosenfeld }
5135*4c3888b8SHans Rosenfeld if (ofst != 0) {
5136*4c3888b8SHans Rosenfeld mcp->mb[10] = LSW(ofst);
5137*4c3888b8SHans Rosenfeld mcp->mb[11] = MSW(ofst);
5138*4c3888b8SHans Rosenfeld }
5139*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|
5140*4c3888b8SHans Rosenfeld MBX_2|MBX_1|MBX_0;
5141*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_15|MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5142*4c3888b8SHans Rosenfeld MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5143*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5144*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5145*4c3888b8SHans Rosenfeld
5146*4c3888b8SHans Rosenfeld /* Return mailbox data. */
5147*4c3888b8SHans Rosenfeld if (mr != NULL) {
5148*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
5149*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
5150*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
5151*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
5152*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
5153*4c3888b8SHans Rosenfeld mr->mb[5] = mcp->mb[5];
5154*4c3888b8SHans Rosenfeld mr->mb[6] = mcp->mb[6];
5155*4c3888b8SHans Rosenfeld mr->mb[7] = mcp->mb[7];
5156*4c3888b8SHans Rosenfeld mr->mb[8] = mcp->mb[8];
5157*4c3888b8SHans Rosenfeld mr->mb[9] = mcp->mb[9];
5158*4c3888b8SHans Rosenfeld mr->mb[10] = mcp->mb[10];
5159*4c3888b8SHans Rosenfeld mr->mb[11] = mcp->mb[11];
5160*4c3888b8SHans Rosenfeld mr->mb[12] = mcp->mb[12];
5161*4c3888b8SHans Rosenfeld mr->mb[13] = mcp->mb[13];
5162*4c3888b8SHans Rosenfeld mr->mb[12] = mcp->mb[14];
5163*4c3888b8SHans Rosenfeld mr->mb[13] = mcp->mb[15];
5164*4c3888b8SHans Rosenfeld }
5165*4c3888b8SHans Rosenfeld
5166*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5167*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh\n", rval);
5168*4c3888b8SHans Rosenfeld } else {
5169*4c3888b8SHans Rosenfeld /*EMPTY*/
5170*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5171*4c3888b8SHans Rosenfeld }
5172*4c3888b8SHans Rosenfeld return (rval);
5173*4c3888b8SHans Rosenfeld }
5174*4c3888b8SHans Rosenfeld
5175*4c3888b8SHans Rosenfeld /*
5176*4c3888b8SHans Rosenfeld * ql_init_req_q
5177*4c3888b8SHans Rosenfeld * Initialize request queue.
5178*4c3888b8SHans Rosenfeld *
5179*4c3888b8SHans Rosenfeld * Input:
5180*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5181*4c3888b8SHans Rosenfeld * req_q: request queue structure pointer.
5182*4c3888b8SHans Rosenfeld * opt: Initialize Multiple Queue mailbox command options.
5183*4c3888b8SHans Rosenfeld *
5184*4c3888b8SHans Rosenfeld * Returns:
5185*4c3888b8SHans Rosenfeld * ql driver local function return status codes
5186*4c3888b8SHans Rosenfeld *
5187*4c3888b8SHans Rosenfeld * Context:
5188*4c3888b8SHans Rosenfeld * Kernel context.
5189*4c3888b8SHans Rosenfeld */
5190*4c3888b8SHans Rosenfeld static int
ql_init_req_q(ql_adapter_state_t * ha,ql_request_q_t * req_q,uint16_t opt)5191*4c3888b8SHans Rosenfeld ql_init_req_q(ql_adapter_state_t *ha, ql_request_q_t *req_q, uint16_t opt)
5192*4c3888b8SHans Rosenfeld {
5193*4c3888b8SHans Rosenfeld int rval;
5194*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5195*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5196*4c3888b8SHans Rosenfeld
5197*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, req_q_number=%d\n", req_q->req_q_number);
5198*4c3888b8SHans Rosenfeld
5199*4c3888b8SHans Rosenfeld if (!(opt & IMO_QOS_UPDATE)) {
5200*4c3888b8SHans Rosenfeld req_q->req_ring_ptr = req_q->req_ring.bp;
5201*4c3888b8SHans Rosenfeld req_q->req_ring_index = 0;
5202*4c3888b8SHans Rosenfeld req_q->req_q_cnt = (uint16_t)(req_q->req_entry_cnt - 1);
5203*4c3888b8SHans Rosenfeld WR32_MBAR_REG(ha, req_q->mbar_req_in, 0);
5204*4c3888b8SHans Rosenfeld if (req_q->req_out_shadow_ptr) {
5205*4c3888b8SHans Rosenfeld *req_q->req_out_shadow_ptr = 0;
5206*4c3888b8SHans Rosenfeld }
5207*4c3888b8SHans Rosenfeld }
5208*4c3888b8SHans Rosenfeld
5209*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5210*4c3888b8SHans Rosenfeld mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED);
5211*4c3888b8SHans Rosenfeld mcp->mb[2] = MSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5212*4c3888b8SHans Rosenfeld mcp->mb[3] = LSW(LSD(req_q->req_ring.cookie.dmac_laddress));
5213*4c3888b8SHans Rosenfeld mcp->mb[4] = req_q->req_q_number;
5214*4c3888b8SHans Rosenfeld mcp->mb[5] = req_q->req_entry_cnt;
5215*4c3888b8SHans Rosenfeld mcp->mb[6] = MSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5216*4c3888b8SHans Rosenfeld mcp->mb[7] = LSW(MSD(req_q->req_ring.cookie.dmac_laddress));
5217*4c3888b8SHans Rosenfeld mcp->mb[11] = ha->vp_index;
5218*4c3888b8SHans Rosenfeld mcp->mb[12] = 0;
5219*4c3888b8SHans Rosenfeld mcp->mb[14] = 1;
5220*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_14;
5221*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_1;
5222*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5223*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5224*4c3888b8SHans Rosenfeld
5225*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5226*4c3888b8SHans Rosenfeld EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5227*4c3888b8SHans Rosenfeld } else {
5228*4c3888b8SHans Rosenfeld /*EMPTY*/
5229*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5230*4c3888b8SHans Rosenfeld }
5231*4c3888b8SHans Rosenfeld return (rval);
5232*4c3888b8SHans Rosenfeld }
5233*4c3888b8SHans Rosenfeld
5234*4c3888b8SHans Rosenfeld /*
5235*4c3888b8SHans Rosenfeld * ql_init_rsp_q
5236*4c3888b8SHans Rosenfeld * Initialize response queue.
5237*4c3888b8SHans Rosenfeld *
5238*4c3888b8SHans Rosenfeld * Input:
5239*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5240*4c3888b8SHans Rosenfeld * rsp_q: response queue structure pointer.
5241*4c3888b8SHans Rosenfeld * opt: Initialize Multiple Queue mailbox command options.
5242*4c3888b8SHans Rosenfeld *
5243*4c3888b8SHans Rosenfeld * Returns:
5244*4c3888b8SHans Rosenfeld * ql driver local function return status codes
5245*4c3888b8SHans Rosenfeld *
5246*4c3888b8SHans Rosenfeld * Context:
5247*4c3888b8SHans Rosenfeld * Kernel context.
5248*4c3888b8SHans Rosenfeld */
5249*4c3888b8SHans Rosenfeld static int
ql_init_rsp_q(ql_adapter_state_t * ha,ql_response_q_t * rsp_q,uint16_t opt)5250*4c3888b8SHans Rosenfeld ql_init_rsp_q(ql_adapter_state_t *ha, ql_response_q_t *rsp_q, uint16_t opt)
5251*4c3888b8SHans Rosenfeld {
5252*4c3888b8SHans Rosenfeld int rval;
5253*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5254*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5255*4c3888b8SHans Rosenfeld
5256*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started, rsp_q_number=%d\n", rsp_q->rsp_q_number);
5257*4c3888b8SHans Rosenfeld
5258*4c3888b8SHans Rosenfeld if (!(opt & IMO_DELETE_Q)) {
5259*4c3888b8SHans Rosenfeld rsp_q->rsp_ring_ptr = rsp_q->rsp_ring.bp;
5260*4c3888b8SHans Rosenfeld rsp_q->rsp_ring_index = 0;
5261*4c3888b8SHans Rosenfeld WR32_MBAR_REG(ha, rsp_q->mbar_rsp_out, 0);
5262*4c3888b8SHans Rosenfeld if (rsp_q->rsp_in_shadow_ptr) {
5263*4c3888b8SHans Rosenfeld *rsp_q->rsp_in_shadow_ptr = 0;
5264*4c3888b8SHans Rosenfeld }
5265*4c3888b8SHans Rosenfeld }
5266*4c3888b8SHans Rosenfeld
5267*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_INIT_MULTIPLE_QUEUE;
5268*4c3888b8SHans Rosenfeld mcp->mb[1] = (uint16_t)(opt | IMO_QUEUE_NOT_ASSOCIATED |
5269*4c3888b8SHans Rosenfeld IMO_RESPONSE_Q_SERVICE);
5270*4c3888b8SHans Rosenfeld mcp->mb[2] = MSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5271*4c3888b8SHans Rosenfeld mcp->mb[3] = LSW(LSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5272*4c3888b8SHans Rosenfeld mcp->mb[4] = rsp_q->rsp_q_number;
5273*4c3888b8SHans Rosenfeld mcp->mb[5] = rsp_q->rsp_entry_cnt;
5274*4c3888b8SHans Rosenfeld mcp->mb[6] = MSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5275*4c3888b8SHans Rosenfeld mcp->mb[7] = LSW(MSD(rsp_q->rsp_ring.cookie.dmac_laddress));
5276*4c3888b8SHans Rosenfeld mcp->mb[14] = rsp_q->msi_x_vector;
5277*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_14;
5278*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_1;
5279*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5280*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5281*4c3888b8SHans Rosenfeld
5282*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5283*4c3888b8SHans Rosenfeld EL(ha, "status=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5284*4c3888b8SHans Rosenfeld } else {
5285*4c3888b8SHans Rosenfeld /*EMPTY*/
5286*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5287*4c3888b8SHans Rosenfeld }
5288*4c3888b8SHans Rosenfeld return (rval);
5289*4c3888b8SHans Rosenfeld }
5290*4c3888b8SHans Rosenfeld
5291*4c3888b8SHans Rosenfeld /*
5292*4c3888b8SHans Rosenfeld * ql_load_flash_image
5293*4c3888b8SHans Rosenfeld * Load Flash Firmware.
5294*4c3888b8SHans Rosenfeld *
5295*4c3888b8SHans Rosenfeld * Input:
5296*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5297*4c3888b8SHans Rosenfeld *
5298*4c3888b8SHans Rosenfeld * Returns:
5299*4c3888b8SHans Rosenfeld * ql local function return status code.
5300*4c3888b8SHans Rosenfeld *
5301*4c3888b8SHans Rosenfeld * Context:
5302*4c3888b8SHans Rosenfeld * Kernel context.
5303*4c3888b8SHans Rosenfeld */
5304*4c3888b8SHans Rosenfeld int
ql_load_flash_image(ql_adapter_state_t * ha)5305*4c3888b8SHans Rosenfeld ql_load_flash_image(ql_adapter_state_t *ha)
5306*4c3888b8SHans Rosenfeld {
5307*4c3888b8SHans Rosenfeld int rval;
5308*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5309*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5310*4c3888b8SHans Rosenfeld
5311*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5312*4c3888b8SHans Rosenfeld
5313*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_LOAD_FLASH_IMAGE;
5314*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0;
5315*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_2|MBX_1|MBX_0;
5316*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5317*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5318*4c3888b8SHans Rosenfeld
5319*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5320*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, mbx1=%xh, mbx2=%xh\n",
5321*4c3888b8SHans Rosenfeld rval, mcp->mb[1], mcp->mb[2]);
5322*4c3888b8SHans Rosenfeld } else {
5323*4c3888b8SHans Rosenfeld /*EMPTY*/
5324*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5325*4c3888b8SHans Rosenfeld }
5326*4c3888b8SHans Rosenfeld return (rval);
5327*4c3888b8SHans Rosenfeld }
5328*4c3888b8SHans Rosenfeld
5329*4c3888b8SHans Rosenfeld /*
5330*4c3888b8SHans Rosenfeld * ql_set_led_config
5331*4c3888b8SHans Rosenfeld * Set LED Configuration.
5332*4c3888b8SHans Rosenfeld *
5333*4c3888b8SHans Rosenfeld * Input:
5334*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5335*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5336*4c3888b8SHans Rosenfeld *
5337*4c3888b8SHans Rosenfeld * Returns:
5338*4c3888b8SHans Rosenfeld * ql local function return status code.
5339*4c3888b8SHans Rosenfeld *
5340*4c3888b8SHans Rosenfeld * Context:
5341*4c3888b8SHans Rosenfeld * Kernel context.
5342*4c3888b8SHans Rosenfeld */
5343*4c3888b8SHans Rosenfeld int
ql_set_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5344*4c3888b8SHans Rosenfeld ql_set_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5345*4c3888b8SHans Rosenfeld {
5346*4c3888b8SHans Rosenfeld int rval;
5347*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5348*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5349*4c3888b8SHans Rosenfeld
5350*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5351*4c3888b8SHans Rosenfeld
5352*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_SET_LED_CONFIG;
5353*4c3888b8SHans Rosenfeld mcp->mb[1] = mr->mb[1];
5354*4c3888b8SHans Rosenfeld mcp->mb[2] = mr->mb[2];
5355*4c3888b8SHans Rosenfeld mcp->mb[3] = mr->mb[3];
5356*4c3888b8SHans Rosenfeld mcp->mb[4] = mr->mb[4];
5357*4c3888b8SHans Rosenfeld mcp->mb[5] = mr->mb[5];
5358*4c3888b8SHans Rosenfeld mcp->mb[6] = mr->mb[6];
5359*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_6;
5360*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0;
5361*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5362*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5363*4c3888b8SHans Rosenfeld
5364*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5365*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh\n", rval);
5366*4c3888b8SHans Rosenfeld } else {
5367*4c3888b8SHans Rosenfeld /*EMPTY*/
5368*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5369*4c3888b8SHans Rosenfeld }
5370*4c3888b8SHans Rosenfeld
5371*4c3888b8SHans Rosenfeld return (rval);
5372*4c3888b8SHans Rosenfeld }
5373*4c3888b8SHans Rosenfeld /*
5374*4c3888b8SHans Rosenfeld * ql_get_led_config
5375*4c3888b8SHans Rosenfeld * Get LED Configuration.
5376*4c3888b8SHans Rosenfeld *
5377*4c3888b8SHans Rosenfeld * Input:
5378*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5379*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5380*4c3888b8SHans Rosenfeld *
5381*4c3888b8SHans Rosenfeld * Returns:
5382*4c3888b8SHans Rosenfeld * ql local function return status code.
5383*4c3888b8SHans Rosenfeld *
5384*4c3888b8SHans Rosenfeld * Context:
5385*4c3888b8SHans Rosenfeld * Kernel context.
5386*4c3888b8SHans Rosenfeld */
5387*4c3888b8SHans Rosenfeld int
ql_get_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5388*4c3888b8SHans Rosenfeld ql_get_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5389*4c3888b8SHans Rosenfeld {
5390*4c3888b8SHans Rosenfeld int rval;
5391*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5392*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5393*4c3888b8SHans Rosenfeld
5394*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5395*4c3888b8SHans Rosenfeld
5396*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_GET_LED_CONFIG;
5397*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0;
5398*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_6;
5399*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5400*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5401*4c3888b8SHans Rosenfeld
5402*4c3888b8SHans Rosenfeld /* Return config data. */
5403*4c3888b8SHans Rosenfeld if (mr != NULL) {
5404*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
5405*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
5406*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
5407*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
5408*4c3888b8SHans Rosenfeld mr->mb[5] = mcp->mb[5];
5409*4c3888b8SHans Rosenfeld mr->mb[6] = mcp->mb[6];
5410*4c3888b8SHans Rosenfeld }
5411*4c3888b8SHans Rosenfeld
5412*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5413*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh\n", rval);
5414*4c3888b8SHans Rosenfeld } else {
5415*4c3888b8SHans Rosenfeld /*EMPTY*/
5416*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5417*4c3888b8SHans Rosenfeld }
5418*4c3888b8SHans Rosenfeld
5419*4c3888b8SHans Rosenfeld return (rval);
5420*4c3888b8SHans Rosenfeld }
5421*4c3888b8SHans Rosenfeld
5422*4c3888b8SHans Rosenfeld /*
5423*4c3888b8SHans Rosenfeld * ql_led_config
5424*4c3888b8SHans Rosenfeld * Set/Get Fibre Channel LED Configuration command.
5425*4c3888b8SHans Rosenfeld *
5426*4c3888b8SHans Rosenfeld * Input:
5427*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5428*4c3888b8SHans Rosenfeld * opt: Options.
5429*4c3888b8SHans Rosenfeld * led0: LED 0 configuration.
5430*4c3888b8SHans Rosenfeld * led1: LED 1 configuration.
5431*4c3888b8SHans Rosenfeld * led2: LED 2 configuration.
5432*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5433*4c3888b8SHans Rosenfeld *
5434*4c3888b8SHans Rosenfeld * Returns:
5435*4c3888b8SHans Rosenfeld * qlc local function return status code.
5436*4c3888b8SHans Rosenfeld *
5437*4c3888b8SHans Rosenfeld * Context:
5438*4c3888b8SHans Rosenfeld * Kernel context.
5439*4c3888b8SHans Rosenfeld */
5440*4c3888b8SHans Rosenfeld int
ql_led_config(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5441*4c3888b8SHans Rosenfeld ql_led_config(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5442*4c3888b8SHans Rosenfeld {
5443*4c3888b8SHans Rosenfeld int rval = QL_SUCCESS;
5444*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5445*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5446*4c3888b8SHans Rosenfeld
5447*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5448*4c3888b8SHans Rosenfeld
5449*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_FC_LED_CONFIG;
5450*4c3888b8SHans Rosenfeld mcp->mb[1] = mr->mb[1];
5451*4c3888b8SHans Rosenfeld mcp->mb[2] = mr->mb[2];
5452*4c3888b8SHans Rosenfeld mcp->mb[3] = mr->mb[3];
5453*4c3888b8SHans Rosenfeld mcp->mb[4] = mr->mb[4];
5454*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_4;
5455*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_4;
5456*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5457*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5458*4c3888b8SHans Rosenfeld
5459*4c3888b8SHans Rosenfeld /* Return mailbox data. */
5460*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
5461*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
5462*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
5463*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
5464*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
5465*4c3888b8SHans Rosenfeld
5466*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5467*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5468*4c3888b8SHans Rosenfeld } else {
5469*4c3888b8SHans Rosenfeld /*EMPTY*/
5470*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5471*4c3888b8SHans Rosenfeld }
5472*4c3888b8SHans Rosenfeld return (rval);
5473*4c3888b8SHans Rosenfeld }
5474*4c3888b8SHans Rosenfeld
5475*4c3888b8SHans Rosenfeld /*
5476*4c3888b8SHans Rosenfeld * ql_write_remote_reg
5477*4c3888b8SHans Rosenfeld * Writes a register within another function.
5478*4c3888b8SHans Rosenfeld *
5479*4c3888b8SHans Rosenfeld * Input:
5480*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5481*4c3888b8SHans Rosenfeld * addr: address.
5482*4c3888b8SHans Rosenfeld * data: data.
5483*4c3888b8SHans Rosenfeld *
5484*4c3888b8SHans Rosenfeld * Returns:
5485*4c3888b8SHans Rosenfeld * ql local function return status code.
5486*4c3888b8SHans Rosenfeld *
5487*4c3888b8SHans Rosenfeld * Context:
5488*4c3888b8SHans Rosenfeld * Kernel context.
5489*4c3888b8SHans Rosenfeld */
5490*4c3888b8SHans Rosenfeld int
ql_write_remote_reg(ql_adapter_state_t * ha,uint32_t addr,uint32_t data)5491*4c3888b8SHans Rosenfeld ql_write_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
5492*4c3888b8SHans Rosenfeld {
5493*4c3888b8SHans Rosenfeld int rval;
5494*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5495*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5496*4c3888b8SHans Rosenfeld
5497*4c3888b8SHans Rosenfeld QL_PRINT_10(ha, "started, addr=%xh, data=%xh\n", addr, data);
5498*4c3888b8SHans Rosenfeld
5499*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5500*4c3888b8SHans Rosenfeld mcp->mb[1] = LSW(addr);
5501*4c3888b8SHans Rosenfeld mcp->mb[2] = MSW(addr);
5502*4c3888b8SHans Rosenfeld mcp->mb[3] = LSW(data);
5503*4c3888b8SHans Rosenfeld mcp->mb[4] = MSW(data);
5504*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5505*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_1|MBX_0;
5506*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5507*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5508*4c3888b8SHans Rosenfeld
5509*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5510*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh, mbx1=%xh, addr=%xh, data=%xh\n", rval,
5511*4c3888b8SHans Rosenfeld mcp->mb[1], addr, data);
5512*4c3888b8SHans Rosenfeld } else {
5513*4c3888b8SHans Rosenfeld /*EMPTY*/
5514*4c3888b8SHans Rosenfeld QL_PRINT_10(ha, "done\n");
5515*4c3888b8SHans Rosenfeld }
5516*4c3888b8SHans Rosenfeld return (rval);
5517*4c3888b8SHans Rosenfeld }
5518*4c3888b8SHans Rosenfeld
5519*4c3888b8SHans Rosenfeld /*
5520*4c3888b8SHans Rosenfeld * ql_read_remote_reg
5521*4c3888b8SHans Rosenfeld * Read a register within another function.
5522*4c3888b8SHans Rosenfeld *
5523*4c3888b8SHans Rosenfeld * Input:
5524*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5525*4c3888b8SHans Rosenfeld * addr: address.
5526*4c3888b8SHans Rosenfeld * data: data pointer.
5527*4c3888b8SHans Rosenfeld *
5528*4c3888b8SHans Rosenfeld * Returns:
5529*4c3888b8SHans Rosenfeld * qlc local function return status code.
5530*4c3888b8SHans Rosenfeld *
5531*4c3888b8SHans Rosenfeld * Context:
5532*4c3888b8SHans Rosenfeld * Kernel context.
5533*4c3888b8SHans Rosenfeld */
5534*4c3888b8SHans Rosenfeld int
ql_read_remote_reg(ql_adapter_state_t * ha,uint32_t addr,uint32_t * dp)5535*4c3888b8SHans Rosenfeld ql_read_remote_reg(ql_adapter_state_t *ha, uint32_t addr, uint32_t *dp)
5536*4c3888b8SHans Rosenfeld {
5537*4c3888b8SHans Rosenfeld int rval;
5538*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5539*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5540*4c3888b8SHans Rosenfeld
5541*4c3888b8SHans Rosenfeld QL_PRINT_10(ha, "started, addr=%xh\n", addr);
5542*4c3888b8SHans Rosenfeld
5543*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_READ_REMOTE_REG;
5544*4c3888b8SHans Rosenfeld mcp->mb[1] = LSW(addr);
5545*4c3888b8SHans Rosenfeld mcp->mb[2] = MSW(addr);
5546*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_2|MBX_1|MBX_0;
5547*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5548*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5549*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5550*4c3888b8SHans Rosenfeld
5551*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5552*4c3888b8SHans Rosenfeld EL(ha, "failed=%xh, mbx1=%xh, addr=%xh\n", rval, mcp->mb[1],
5553*4c3888b8SHans Rosenfeld addr);
5554*4c3888b8SHans Rosenfeld } else {
5555*4c3888b8SHans Rosenfeld *dp = SHORT_TO_LONG(mcp->mb[3], mcp->mb[4]);
5556*4c3888b8SHans Rosenfeld QL_PRINT_10(ha, "done, addr=%xh, data=%xh\n", addr, *dp);
5557*4c3888b8SHans Rosenfeld }
5558*4c3888b8SHans Rosenfeld return (rval);
5559*4c3888b8SHans Rosenfeld }
5560*4c3888b8SHans Rosenfeld
5561*4c3888b8SHans Rosenfeld /*
5562*4c3888b8SHans Rosenfeld * ql_get_temp
5563*4c3888b8SHans Rosenfeld * Issue get temperature mailbox command.
5564*4c3888b8SHans Rosenfeld *
5565*4c3888b8SHans Rosenfeld * Input:
5566*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5567*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5568*4c3888b8SHans Rosenfeld *
5569*4c3888b8SHans Rosenfeld * Returns:
5570*4c3888b8SHans Rosenfeld * ql local function return status code.
5571*4c3888b8SHans Rosenfeld *
5572*4c3888b8SHans Rosenfeld * Context:
5573*4c3888b8SHans Rosenfeld * Kernel context.
5574*4c3888b8SHans Rosenfeld */
5575*4c3888b8SHans Rosenfeld int
ql_get_temp(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5576*4c3888b8SHans Rosenfeld ql_get_temp(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5577*4c3888b8SHans Rosenfeld {
5578*4c3888b8SHans Rosenfeld int rval;
5579*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5580*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5581*4c3888b8SHans Rosenfeld
5582*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5583*4c3888b8SHans Rosenfeld
5584*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_GET_PARAMETERS;
5585*4c3888b8SHans Rosenfeld mcp->mb[1] = READ_ASIC_TEMP << 8;
5586*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_1;
5587*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_1;
5588*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5589*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5590*4c3888b8SHans Rosenfeld
5591*4c3888b8SHans Rosenfeld /* Return config data. */
5592*4c3888b8SHans Rosenfeld if (mr != NULL) {
5593*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
5594*4c3888b8SHans Rosenfeld }
5595*4c3888b8SHans Rosenfeld
5596*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5597*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh, mbx1=%xh\n", rval, mcp->mb[1]);
5598*4c3888b8SHans Rosenfeld } else {
5599*4c3888b8SHans Rosenfeld /*EMPTY*/
5600*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5601*4c3888b8SHans Rosenfeld }
5602*4c3888b8SHans Rosenfeld return (rval);
5603*4c3888b8SHans Rosenfeld }
5604*4c3888b8SHans Rosenfeld
5605*4c3888b8SHans Rosenfeld /*
5606*4c3888b8SHans Rosenfeld * ql_write_serdes
5607*4c3888b8SHans Rosenfeld * Issue write FC serdes register mailbox command.
5608*4c3888b8SHans Rosenfeld *
5609*4c3888b8SHans Rosenfeld * Input:
5610*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5611*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5612*4c3888b8SHans Rosenfeld *
5613*4c3888b8SHans Rosenfeld * Returns:
5614*4c3888b8SHans Rosenfeld * ql local function return status code.
5615*4c3888b8SHans Rosenfeld *
5616*4c3888b8SHans Rosenfeld * Context:
5617*4c3888b8SHans Rosenfeld * Kernel context.
5618*4c3888b8SHans Rosenfeld */
5619*4c3888b8SHans Rosenfeld int
ql_write_serdes(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5620*4c3888b8SHans Rosenfeld ql_write_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5621*4c3888b8SHans Rosenfeld {
5622*4c3888b8SHans Rosenfeld int rval;
5623*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5624*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5625*4c3888b8SHans Rosenfeld
5626*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5627*4c3888b8SHans Rosenfeld
5628*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_WRITE_SERDES_REG;
5629*4c3888b8SHans Rosenfeld mcp->mb[1] = mr->mb[1];
5630*4c3888b8SHans Rosenfeld mcp->mb[2] = mr->mb[2];
5631*4c3888b8SHans Rosenfeld mcp->mb[3] = mr->mb[3];
5632*4c3888b8SHans Rosenfeld mcp->mb[4] = mr->mb[4];
5633*4c3888b8SHans Rosenfeld mcp->mb[5] = mr->mb[5];
5634*4c3888b8SHans Rosenfeld mcp->mb[6] = mr->mb[6];
5635*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_6;
5636*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0;
5637*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5638*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5639*4c3888b8SHans Rosenfeld
5640*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5641*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh\n", rval);
5642*4c3888b8SHans Rosenfeld } else {
5643*4c3888b8SHans Rosenfeld /*EMPTY*/
5644*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5645*4c3888b8SHans Rosenfeld }
5646*4c3888b8SHans Rosenfeld
5647*4c3888b8SHans Rosenfeld return (rval);
5648*4c3888b8SHans Rosenfeld }
5649*4c3888b8SHans Rosenfeld
5650*4c3888b8SHans Rosenfeld /*
5651*4c3888b8SHans Rosenfeld * ql_read_serdes
5652*4c3888b8SHans Rosenfeld * Issue read FC serdes register mailbox command.
5653*4c3888b8SHans Rosenfeld *
5654*4c3888b8SHans Rosenfeld * Input:
5655*4c3888b8SHans Rosenfeld * ha: adapter state pointer.
5656*4c3888b8SHans Rosenfeld * mr: pointer for mailbox data.
5657*4c3888b8SHans Rosenfeld *
5658*4c3888b8SHans Rosenfeld * Returns:
5659*4c3888b8SHans Rosenfeld * ql local function return status code.
5660*4c3888b8SHans Rosenfeld *
5661*4c3888b8SHans Rosenfeld * Context:
5662*4c3888b8SHans Rosenfeld * Kernel context.
5663*4c3888b8SHans Rosenfeld */
5664*4c3888b8SHans Rosenfeld int
ql_read_serdes(ql_adapter_state_t * ha,ql_mbx_data_t * mr)5665*4c3888b8SHans Rosenfeld ql_read_serdes(ql_adapter_state_t *ha, ql_mbx_data_t *mr)
5666*4c3888b8SHans Rosenfeld {
5667*4c3888b8SHans Rosenfeld int rval;
5668*4c3888b8SHans Rosenfeld mbx_cmd_t mc = {0};
5669*4c3888b8SHans Rosenfeld mbx_cmd_t *mcp = &mc;
5670*4c3888b8SHans Rosenfeld
5671*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "started\n");
5672*4c3888b8SHans Rosenfeld
5673*4c3888b8SHans Rosenfeld mcp->mb[0] = MBC_READ_SERDES_REG;
5674*4c3888b8SHans Rosenfeld mcp->mb[1] = mr->mb[1];
5675*4c3888b8SHans Rosenfeld mcp->mb[2] = mr->mb[2];
5676*4c3888b8SHans Rosenfeld mcp->mb[3] = mr->mb[3];
5677*4c3888b8SHans Rosenfeld mcp->mb[4] = mr->mb[4];
5678*4c3888b8SHans Rosenfeld mcp->mb[5] = mr->mb[5];
5679*4c3888b8SHans Rosenfeld mcp->mb[6] = mr->mb[6];
5680*4c3888b8SHans Rosenfeld mcp->out_mb = MBX_0_THRU_6;
5681*4c3888b8SHans Rosenfeld mcp->in_mb = MBX_0_THRU_6;
5682*4c3888b8SHans Rosenfeld mcp->timeout = MAILBOX_TOV;
5683*4c3888b8SHans Rosenfeld rval = ql_mailbox_command(ha, mcp);
5684*4c3888b8SHans Rosenfeld
5685*4c3888b8SHans Rosenfeld /* Return mailbox data. */
5686*4c3888b8SHans Rosenfeld mr->mb[0] = mcp->mb[0];
5687*4c3888b8SHans Rosenfeld mr->mb[1] = mcp->mb[1];
5688*4c3888b8SHans Rosenfeld mr->mb[2] = mcp->mb[2];
5689*4c3888b8SHans Rosenfeld mr->mb[3] = mcp->mb[3];
5690*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[4];
5691*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[5];
5692*4c3888b8SHans Rosenfeld mr->mb[4] = mcp->mb[6];
5693*4c3888b8SHans Rosenfeld
5694*4c3888b8SHans Rosenfeld if (rval != QL_SUCCESS) {
5695*4c3888b8SHans Rosenfeld EL(ha, "failed, rval=%xh", rval);
5696*4c3888b8SHans Rosenfeld } else {
5697*4c3888b8SHans Rosenfeld /*EMPTY*/
5698*4c3888b8SHans Rosenfeld QL_PRINT_3(ha, "done\n");
5699eb82ff87SDaniel Beauregard }
5700eb82ff87SDaniel Beauregard
5701eb82ff87SDaniel Beauregard return (rval);
5702eb82ff87SDaniel Beauregard }
5703