blob: bde3eb273b0d76a1d351679853bee04364929056 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Andrew Vasquez07e264b2011-03-30 11:46:23 -07003 * Copyright (c) 2003-2011 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090010#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
13/*
14 * qla2x00_mailbox_command
15 * Issue mailbox command and waits for completion.
16 *
17 * Input:
18 * ha = adapter block pointer.
19 * mcp = driver internal mbx struct pointer.
20 *
21 * Output:
22 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
23 *
24 * Returns:
25 * 0 : QLA_SUCCESS = cmd performed success
26 * 1 : QLA_FUNCTION_FAILED (error encountered)
27 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
28 *
29 * Context:
30 * Kernel context.
31 */
32static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080033qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070034{
35 int rval;
36 unsigned long flags = 0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070037 device_reg_t __iomem *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070038 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070039 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -070040 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 uint16_t *iptr;
42 uint16_t __iomem *optr;
43 uint32_t cnt;
44 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080046 struct qla_hw_data *ha = vha->hw;
47 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070048
Saurav Kashyap7c3df132011-07-14 12:00:13 -070049 ql_dbg(ql_dbg_mbx, base_vha, 0x1000, "Entered %s.\n", __func__);
50
51 if (ha->pdev->error_state > pci_channel_io_frozen) {
52 ql_log(ql_log_warn, base_vha, 0x1001,
53 "error_state is greater than pci_channel_io_frozen, "
54 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070055 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070056 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070057
Giridhar Malavalia9083012010-04-12 17:59:55 -070058 if (vha->device_flags & DFLG_DEV_FAILED) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070059 ql_log(ql_log_warn, base_vha, 0x1002,
60 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070061 return QLA_FUNCTION_TIMEOUT;
62 }
63
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070064 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080065 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070070
Andrew Vasquez85880802009-12-15 21:29:46 -080071 if (ha->flags.pci_channel_io_perm_failure) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070072 ql_log(ql_log_warn, base_vha, 0x1003,
73 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080074 return QLA_FUNCTION_TIMEOUT;
75 }
76
Giridhar Malavali862cd012011-02-23 15:27:11 -080077 if (ha->flags.isp82xx_fw_hung) {
78 /* Setting Link-Down error */
79 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070080 ql_log(ql_log_warn, base_vha, 0x1004,
81 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080082 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080083 }
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070086 * Wait for active mailbox commands to finish by waiting at most tov
87 * seconds. This is to serialize actual issuing of mailbox cmds during
88 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080090 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
91 /* Timeout occurred. Return error. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -070092 ql_log(ql_log_warn, base_vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080093 "Cmd access timeout, cmd=0x%x, Exiting.\n",
94 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080095 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 }
97
98 ha->flags.mbox_busy = 1;
99 /* Save mailbox command for debug */
100 ha->mcp = mcp;
101
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700102 ql_dbg(ql_dbg_mbx, base_vha, 0x1006,
103 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
105 spin_lock_irqsave(&ha->hardware_lock, flags);
106
107 /* Load mailbox registers. */
Giridhar Malavalia9083012010-04-12 17:59:55 -0700108 if (IS_QLA82XX(ha))
109 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
110 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700111 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
112 else
113 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
115 iptr = mcp->mb;
116 command = mcp->mb[0];
117 mboxes = mcp->out_mb;
118
119 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
120 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700121 optr =
122 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 if (mboxes & BIT_0)
124 WRT_REG_WORD(optr, *iptr);
125
126 mboxes >>= 1;
127 optr++;
128 iptr++;
129 }
130
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700131 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1111,
132 "Loaded MBX registers (displayed in bytes) =.\n");
133 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1112,
134 (uint8_t *)mcp->mb, 16);
135 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1113,
136 ".\n");
137 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1114,
138 ((uint8_t *)mcp->mb + 0x10), 16);
139 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1115,
140 ".\n");
141 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1116,
142 ((uint8_t *)mcp->mb + 0x20), 8);
143 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1117,
144 "I/O Address = %p.\n", optr);
145 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x100e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147 /* Issue set host interrupt command to send cmd out. */
148 ha->flags.mbox_int = 0;
149 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
150
151 /* Unlock mbx registers and wait for interrupt */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700152 ql_dbg(ql_dbg_mbx, base_vha, 0x100f,
153 "Going to unlock irq & waiting for interrupts. "
154 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
156 /* Wait for mbx cmd completion until timeout */
157
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800158 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
160
Giridhar Malavalia9083012010-04-12 17:59:55 -0700161 if (IS_QLA82XX(ha)) {
162 if (RD_REG_DWORD(&reg->isp82.hint) &
163 HINT_MBX_INT_PENDING) {
164 spin_unlock_irqrestore(&ha->hardware_lock,
165 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800166 ha->flags.mbox_busy = 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700167 ql_dbg(ql_dbg_mbx, base_vha, 0x1010,
168 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700169 rval = QLA_FUNCTION_TIMEOUT;
170 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700171 }
172 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
173 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700174 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
175 else
176 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 spin_unlock_irqrestore(&ha->hardware_lock, flags);
178
Marcus Barrow0b05a1f2008-01-17 09:02:13 -0800179 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
182
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700184 ql_dbg(ql_dbg_mbx, base_vha, 0x1011,
185 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Giridhar Malavalia9083012010-04-12 17:59:55 -0700187 if (IS_QLA82XX(ha)) {
188 if (RD_REG_DWORD(&reg->isp82.hint) &
189 HINT_MBX_INT_PENDING) {
190 spin_unlock_irqrestore(&ha->hardware_lock,
191 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800192 ha->flags.mbox_busy = 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700193 ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
194 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700195 rval = QLA_FUNCTION_TIMEOUT;
196 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700197 }
198 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
199 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700200 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
201 else
202 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
206 while (!ha->flags.mbox_int) {
207 if (time_after(jiffies, wait_time))
208 break;
209
210 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800211 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Andrew Vasquez85880802009-12-15 21:29:46 -0800213 if (!ha->flags.mbox_int &&
214 !(IS_QLA2200(ha) &&
215 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800216 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 } /* while */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700218 ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
219 "Waited %d sec.\n",
220 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 }
222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 /* Check whether we timed out */
224 if (ha->flags.mbox_int) {
225 uint16_t *iptr2;
226
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700227 ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
228 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230 /* Got interrupt. Clear the flag. */
231 ha->flags.mbox_int = 0;
232 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
233
Giridhar Malavali71905752011-02-23 15:27:10 -0800234 if (ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700235 ha->flags.mbox_busy = 0;
236 /* Setting Link-Down error */
237 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
238 ha->mcp = NULL;
239 rval = QLA_FUNCTION_FAILED;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700240 ql_log(ql_log_warn, base_vha, 0x1015,
241 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700242 goto premature_exit;
243 }
244
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400245 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248 /* Load return mailbox registers. */
249 iptr2 = mcp->mb;
250 iptr = (uint16_t *)&ha->mailbox_out[0];
251 mboxes = mcp->in_mb;
252 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
253 if (mboxes & BIT_0)
254 *iptr2 = *iptr;
255
256 mboxes >>= 1;
257 iptr2++;
258 iptr++;
259 }
260 } else {
261
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700262 uint16_t mb0;
263 uint32_t ictrl;
264
Andrew Vasqueze4289242007-07-19 15:05:56 -0700265 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700266 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
267 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
268 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700269 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700270 ictrl = RD_REG_WORD(&reg->isp.ictrl);
271 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700272 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
273 "MBX Command timeout for cmd %x.\n", command);
274 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
275 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
276 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
277 "mb[0] = 0x%x.\n", mb0);
278 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 rval = QLA_FUNCTION_TIMEOUT;
281 }
282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 ha->flags.mbox_busy = 0;
284
285 /* Clean up */
286 ha->mcp = NULL;
287
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800288 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700289 ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
290 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291
292 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800293 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 }
295
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700296 if (rval == QLA_FUNCTION_TIMEOUT &&
297 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800298 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
299 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 /* not in dpc. schedule it for dpc to take over. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700301 ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
302 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700303
304 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
305 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
306 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800307 if (IS_QLA82XX(ha)) {
308 ql_dbg(ql_dbg_mbx, vha, 0x112a,
309 "disabling pause transmit on port "
310 "0 & 1.\n");
311 qla82xx_wr_32(ha,
312 QLA82XX_CRB_NIU + 0x98,
313 CRB_NIU_XG_PAUSE_CTL_P0|
314 CRB_NIU_XG_PAUSE_CTL_P1);
315 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700316 ql_log(ql_log_info, base_vha, 0x101c,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800317 "Mailbox cmd timeout occured, cmd=0x%x, "
318 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
319 "abort.\n", command, mcp->mb[0],
320 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700321 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
322 qla2xxx_wake_dpc(vha);
323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 /* call abort directly since we are in the DPC thread */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700326 ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
327 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700329 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
330 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
331 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800332 if (IS_QLA82XX(ha)) {
333 ql_dbg(ql_dbg_mbx, vha, 0x112b,
334 "disabling pause transmit on port "
335 "0 & 1.\n");
336 qla82xx_wr_32(ha,
337 QLA82XX_CRB_NIU + 0x98,
338 CRB_NIU_XG_PAUSE_CTL_P0|
339 CRB_NIU_XG_PAUSE_CTL_P1);
340 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700341 ql_log(ql_log_info, base_vha, 0x101e,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800342 "Mailbox cmd timeout occured, cmd=0x%x, "
343 "mb[0]=0x%x. Scheduling ISP abort ",
344 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700345 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
346 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800347 /* Allow next mbx cmd to come in. */
348 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700349 if (ha->isp_ops->abort_isp(vha)) {
350 /* Failed. retry later. */
351 set_bit(ISP_ABORT_NEEDED,
352 &vha->dpc_flags);
353 }
354 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700355 ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
356 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800357 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 }
360 }
361
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700362premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800364 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Giridhar Malavalid3360962012-02-09 11:14:10 -0800366mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 if (rval) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700368 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800369 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
370 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700372 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 }
374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 return rval;
376}
377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800379qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800380 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
382 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800383 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 mbx_cmd_t mc;
385 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700387 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Andrew Vasqueze4289242007-07-19 15:05:56 -0700389 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800390 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
391 mcp->mb[8] = MSW(risc_addr);
392 mcp->out_mb = MBX_8|MBX_0;
393 } else {
394 mcp->mb[0] = MBC_LOAD_RISC_RAM;
395 mcp->out_mb = MBX_0;
396 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 mcp->mb[1] = LSW(risc_addr);
398 mcp->mb[2] = MSW(req_dma);
399 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 mcp->mb[6] = MSW(MSD(req_dma));
401 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800402 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700403 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700404 mcp->mb[4] = MSW(risc_code_size);
405 mcp->mb[5] = LSW(risc_code_size);
406 mcp->out_mb |= MBX_5|MBX_4;
407 } else {
408 mcp->mb[4] = LSW(risc_code_size);
409 mcp->out_mb |= MBX_4;
410 }
411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700413 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800415 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700418 ql_dbg(ql_dbg_mbx, vha, 0x1023,
419 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700421 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 }
423
424 return rval;
425}
426
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700427#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428/*
429 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700430 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 *
432 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700433 * ha = adapter block pointer.
434 * TARGET_QUEUE_LOCK must be released.
435 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 *
437 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700438 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 *
440 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700441 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 */
443int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800444qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445{
446 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800447 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 mbx_cmd_t mc;
449 mbx_cmd_t *mcp = &mc;
450
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700451 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452
453 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700454 mcp->out_mb = MBX_0;
455 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700456 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700457 mcp->mb[1] = MSW(risc_addr);
458 mcp->mb[2] = LSW(risc_addr);
459 mcp->mb[3] = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800460 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700461 struct nvram_81xx *nv = ha->nvram;
462 mcp->mb[4] = (nv->enhanced_features &
463 EXTENDED_BB_CREDITS);
464 } else
465 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700466 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700467 mcp->in_mb |= MBX_1;
468 } else {
469 mcp->mb[1] = LSW(risc_addr);
470 mcp->out_mb |= MBX_1;
471 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
472 mcp->mb[2] = 0;
473 mcp->out_mb |= MBX_2;
474 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 }
476
Ravi Anandb93480e2008-04-03 13:13:25 -0700477 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800479 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700481 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700482 ql_dbg(ql_dbg_mbx, vha, 0x1026,
483 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700484 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700485 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700486 ql_dbg(ql_dbg_mbx, vha, 0x1027,
487 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700488 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700489 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700490 }
491 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 return rval;
494}
495
496/*
497 * qla2x00_get_fw_version
498 * Get firmware version.
499 *
500 * Input:
501 * ha: adapter state pointer.
502 * major: pointer for major number.
503 * minor: pointer for minor number.
504 * subminor: pointer for subminor number.
505 *
506 * Returns:
507 * qla2x00 local function return status code.
508 *
509 * Context:
510 * Kernel context.
511 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700512int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800513qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
515 int rval;
516 mbx_cmd_t mc;
517 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800518 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700520 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521
522 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
523 mcp->out_mb = MBX_0;
524 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800525 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700526 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800527 if (IS_QLA83XX(vha->hw))
528 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700530 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800531 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700532 if (rval != QLA_SUCCESS)
533 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800536 ha->fw_major_version = mcp->mb[1];
537 ha->fw_minor_version = mcp->mb[2];
538 ha->fw_subminor_version = mcp->mb[3];
539 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800540 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800541 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800543 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
544 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
545 ha->mpi_version[0] = mcp->mb[10] & 0xff;
546 ha->mpi_version[1] = mcp->mb[11] >> 8;
547 ha->mpi_version[2] = mcp->mb[11] & 0xff;
548 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
549 ha->phy_version[0] = mcp->mb[8] & 0xff;
550 ha->phy_version[1] = mcp->mb[9] >> 8;
551 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800552 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800553 if (IS_QLA83XX(ha)) {
554 if (mcp->mb[6] & BIT_15) {
555 ha->fw_attributes_h = mcp->mb[15];
556 ha->fw_attributes_ext[0] = mcp->mb[16];
557 ha->fw_attributes_ext[1] = mcp->mb[17];
558 ql_dbg(ql_dbg_mbx, vha, 0x1139,
559 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
560 __func__, mcp->mb[15], mcp->mb[6]);
561 } else
562 ql_dbg(ql_dbg_mbx, vha, 0x112f,
563 "%s: FwAttributes [Upper] invalid, MB6:%04x\n",
564 __func__, mcp->mb[6]);
565 }
566
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700567failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 if (rval != QLA_SUCCESS) {
569 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700570 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 } else {
572 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700573 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700575 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576}
577
578/*
579 * qla2x00_get_fw_options
580 * Set firmware options.
581 *
582 * Input:
583 * ha = adapter block pointer.
584 * fwopt = pointer for firmware options.
585 *
586 * Returns:
587 * qla2x00 local function return status code.
588 *
589 * Context:
590 * Kernel context.
591 */
592int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800593qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594{
595 int rval;
596 mbx_cmd_t mc;
597 mbx_cmd_t *mcp = &mc;
598
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700599 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
601 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
602 mcp->out_mb = MBX_0;
603 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700604 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800606 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607
608 if (rval != QLA_SUCCESS) {
609 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700610 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700612 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 fwopts[1] = mcp->mb[1];
614 fwopts[2] = mcp->mb[2];
615 fwopts[3] = mcp->mb[3];
616
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700617 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 }
619
620 return rval;
621}
622
623
624/*
625 * qla2x00_set_fw_options
626 * Set firmware options.
627 *
628 * Input:
629 * ha = adapter block pointer.
630 * fwopt = pointer for firmware options.
631 *
632 * Returns:
633 * qla2x00 local function return status code.
634 *
635 * Context:
636 * Kernel context.
637 */
638int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800639qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640{
641 int rval;
642 mbx_cmd_t mc;
643 mbx_cmd_t *mcp = &mc;
644
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700645 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
647 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
648 mcp->mb[1] = fwopts[1];
649 mcp->mb[2] = fwopts[2];
650 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700651 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800653 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700654 mcp->in_mb |= MBX_1;
655 } else {
656 mcp->mb[10] = fwopts[10];
657 mcp->mb[11] = fwopts[11];
658 mcp->mb[12] = 0; /* Undocumented, but used */
659 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
660 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700661 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800663 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700665 fwopts[0] = mcp->mb[0];
666
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 if (rval != QLA_SUCCESS) {
668 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700669 ql_dbg(ql_dbg_mbx, vha, 0x1030,
670 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 } else {
672 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700673 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 }
675
676 return rval;
677}
678
679/*
680 * qla2x00_mbx_reg_test
681 * Mailbox register wrap test.
682 *
683 * Input:
684 * ha = adapter block pointer.
685 * TARGET_QUEUE_LOCK must be released.
686 * ADAPTER_STATE_LOCK must be released.
687 *
688 * Returns:
689 * qla2x00 local function return status code.
690 *
691 * Context:
692 * Kernel context.
693 */
694int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800695qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696{
697 int rval;
698 mbx_cmd_t mc;
699 mbx_cmd_t *mcp = &mc;
700
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700701 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702
703 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
704 mcp->mb[1] = 0xAAAA;
705 mcp->mb[2] = 0x5555;
706 mcp->mb[3] = 0xAA55;
707 mcp->mb[4] = 0x55AA;
708 mcp->mb[5] = 0xA5A5;
709 mcp->mb[6] = 0x5A5A;
710 mcp->mb[7] = 0x2525;
711 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
712 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700713 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800715 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716
717 if (rval == QLA_SUCCESS) {
718 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
719 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
720 rval = QLA_FUNCTION_FAILED;
721 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
722 mcp->mb[7] != 0x2525)
723 rval = QLA_FUNCTION_FAILED;
724 }
725
726 if (rval != QLA_SUCCESS) {
727 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700728 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 } else {
730 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700731 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 }
733
734 return rval;
735}
736
737/*
738 * qla2x00_verify_checksum
739 * Verify firmware checksum.
740 *
741 * Input:
742 * ha = adapter block pointer.
743 * TARGET_QUEUE_LOCK must be released.
744 * ADAPTER_STATE_LOCK must be released.
745 *
746 * Returns:
747 * qla2x00 local function return status code.
748 *
749 * Context:
750 * Kernel context.
751 */
752int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800753qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754{
755 int rval;
756 mbx_cmd_t mc;
757 mbx_cmd_t *mcp = &mc;
758
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700759 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
761 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700762 mcp->out_mb = MBX_0;
763 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800764 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700765 mcp->mb[1] = MSW(risc_addr);
766 mcp->mb[2] = LSW(risc_addr);
767 mcp->out_mb |= MBX_2|MBX_1;
768 mcp->in_mb |= MBX_2|MBX_1;
769 } else {
770 mcp->mb[1] = LSW(risc_addr);
771 mcp->out_mb |= MBX_1;
772 mcp->in_mb |= MBX_1;
773 }
774
Ravi Anandb93480e2008-04-03 13:13:25 -0700775 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800777 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
779 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700780 ql_dbg(ql_dbg_mbx, vha, 0x1036,
781 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
782 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700784 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 }
786
787 return rval;
788}
789
790/*
791 * qla2x00_issue_iocb
792 * Issue IOCB using mailbox command
793 *
794 * Input:
795 * ha = adapter state pointer.
796 * buffer = buffer pointer.
797 * phys_addr = physical address of buffer.
798 * size = size of buffer.
799 * TARGET_QUEUE_LOCK must be released.
800 * ADAPTER_STATE_LOCK must be released.
801 *
802 * Returns:
803 * qla2x00 local function return status code.
804 *
805 * Context:
806 * Kernel context.
807 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700808int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800809qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700810 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811{
812 int rval;
813 mbx_cmd_t mc;
814 mbx_cmd_t *mcp = &mc;
815
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700816 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
819 mcp->mb[1] = 0;
820 mcp->mb[2] = MSW(phys_addr);
821 mcp->mb[3] = LSW(phys_addr);
822 mcp->mb[6] = MSW(MSD(phys_addr));
823 mcp->mb[7] = LSW(MSD(phys_addr));
824 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
825 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700826 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800828 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
830 if (rval != QLA_SUCCESS) {
831 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700832 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700834 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
835
836 /* Mask reserved bits. */
837 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800838 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700839 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 }
841
842 return rval;
843}
844
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700845int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800846qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700847 size_t size)
848{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800849 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700850 MBX_TOV_SECONDS);
851}
852
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853/*
854 * qla2x00_abort_command
855 * Abort command aborts a specified IOCB.
856 *
857 * Input:
858 * ha = adapter block pointer.
859 * sp = SB structure pointer.
860 *
861 * Returns:
862 * qla2x00 local function return status code.
863 *
864 * Context:
865 * Kernel context.
866 */
867int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700868qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869{
870 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800872 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 mbx_cmd_t mc;
874 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700875 fc_port_t *fcport = sp->fcport;
876 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800877 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700878 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800879 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700881 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700883 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800885 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 break;
887 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700888 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889
890 if (handle == MAX_OUTSTANDING_COMMANDS) {
891 /* command not found */
892 return QLA_FUNCTION_FAILED;
893 }
894
895 mcp->mb[0] = MBC_ABORT_COMMAND;
896 if (HAS_EXTENDED_IDS(ha))
897 mcp->mb[1] = fcport->loop_id;
898 else
899 mcp->mb[1] = fcport->loop_id << 8;
900 mcp->mb[2] = (uint16_t)handle;
901 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800902 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
904 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700905 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800907 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908
909 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700910 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700912 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 }
914
915 return rval;
916}
917
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700919qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700921 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 mbx_cmd_t mc;
923 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800924 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800925 struct req_que *req;
926 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Andrew Vasquez523ec772008-04-03 13:13:24 -0700928 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800929 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700930
931 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
932
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700933 req = vha->hw->req_q_map[0];
934 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700936 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800937 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 mcp->mb[1] = fcport->loop_id;
939 mcp->mb[10] = 0;
940 mcp->out_mb |= MBX_10;
941 } else {
942 mcp->mb[1] = fcport->loop_id << 8;
943 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800944 mcp->mb[2] = vha->hw->loop_reset_delay;
945 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700948 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800950 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700952 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700953 }
954
955 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800956 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
957 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700958 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700959 ql_dbg(ql_dbg_mbx, vha, 0x1040,
960 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700962 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700963 }
964
965 return rval;
966}
967
968int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700969qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700970{
971 int rval, rval2;
972 mbx_cmd_t mc;
973 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800974 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800975 struct req_que *req;
976 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700977
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800978 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700979
980 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
981
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700982 req = vha->hw->req_q_map[0];
983 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700984 mcp->mb[0] = MBC_LUN_RESET;
985 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800986 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700987 mcp->mb[1] = fcport->loop_id;
988 else
989 mcp->mb[1] = fcport->loop_id << 8;
990 mcp->mb[2] = l;
991 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800992 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700993
994 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700995 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700996 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800997 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700998 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700999 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001000 }
1001
1002 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001003 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1004 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001005 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001006 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1007 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001008 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001009 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 }
1011
1012 return rval;
1013}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
1015/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 * qla2x00_get_adapter_id
1017 * Get adapter ID and topology.
1018 *
1019 * Input:
1020 * ha = adapter block pointer.
1021 * id = pointer for loop ID.
1022 * al_pa = pointer for AL_PA.
1023 * area = pointer for area.
1024 * domain = pointer for domain.
1025 * top = pointer for topology.
1026 * TARGET_QUEUE_LOCK must be released.
1027 * ADAPTER_STATE_LOCK must be released.
1028 *
1029 * Returns:
1030 * qla2x00 local function return status code.
1031 *
1032 * Context:
1033 * Kernel context.
1034 */
1035int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001036qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001037 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038{
1039 int rval;
1040 mbx_cmd_t mc;
1041 mbx_cmd_t *mcp = &mc;
1042
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001043 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044
1045 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001046 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001047 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001048 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001049 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001050 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001051 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001053 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001054 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1055 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001056 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1057 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059 /* Return data. */
1060 *id = mcp->mb[1];
1061 *al_pa = LSB(mcp->mb[2]);
1062 *area = MSB(mcp->mb[2]);
1063 *domain = LSB(mcp->mb[3]);
1064 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001065 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067 if (rval != QLA_SUCCESS) {
1068 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001069 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001071 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001072
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001073 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001074 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1075 vha->fcoe_fcf_idx = mcp->mb[10];
1076 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1077 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1078 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1079 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1080 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1081 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1082 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 }
1084
1085 return rval;
1086}
1087
1088/*
1089 * qla2x00_get_retry_cnt
1090 * Get current firmware login retry count and delay.
1091 *
1092 * Input:
1093 * ha = adapter block pointer.
1094 * retry_cnt = pointer to login retry count.
1095 * tov = pointer to login timeout value.
1096 *
1097 * Returns:
1098 * qla2x00 local function return status code.
1099 *
1100 * Context:
1101 * Kernel context.
1102 */
1103int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001104qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 uint16_t *r_a_tov)
1106{
1107 int rval;
1108 uint16_t ratov;
1109 mbx_cmd_t mc;
1110 mbx_cmd_t *mcp = &mc;
1111
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001112 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113
1114 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1115 mcp->out_mb = MBX_0;
1116 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001117 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001119 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
1121 if (rval != QLA_SUCCESS) {
1122 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001123 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1124 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 } else {
1126 /* Convert returned data and check our values. */
1127 *r_a_tov = mcp->mb[3] / 2;
1128 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1129 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1130 /* Update to the larger values */
1131 *retry_cnt = (uint8_t)mcp->mb[1];
1132 *tov = ratov;
1133 }
1134
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001135 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1136 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 }
1138
1139 return rval;
1140}
1141
1142/*
1143 * qla2x00_init_firmware
1144 * Initialize adapter firmware.
1145 *
1146 * Input:
1147 * ha = adapter block pointer.
1148 * dptr = Initialization control block pointer.
1149 * size = size of initialization control block.
1150 * TARGET_QUEUE_LOCK must be released.
1151 * ADAPTER_STATE_LOCK must be released.
1152 *
1153 * Returns:
1154 * qla2x00 local function return status code.
1155 *
1156 * Context:
1157 * Kernel context.
1158 */
1159int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001160qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161{
1162 int rval;
1163 mbx_cmd_t mc;
1164 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001165 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001167 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
Giridhar Malavalia9083012010-04-12 17:59:55 -07001169 if (IS_QLA82XX(ha) && ql2xdbwr)
1170 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1171 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1172
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001173 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001174 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1175 else
1176 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1177
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001178 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 mcp->mb[2] = MSW(ha->init_cb_dma);
1180 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1182 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001183 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001184 if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001185 mcp->mb[1] = BIT_0;
1186 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1187 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1188 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1189 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1190 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1191 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1192 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001193 /* 1 and 2 should normally be captured. */
1194 mcp->in_mb = MBX_2|MBX_1|MBX_0;
1195 if (IS_QLA83XX(ha))
1196 /* mb3 is additional info about the installed SFP. */
1197 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 mcp->buf_size = size;
1199 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001200 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001201 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
1203 if (rval != QLA_SUCCESS) {
1204 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001205 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001206 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1207 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 } else {
1209 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001210 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 }
1212
1213 return rval;
1214}
1215
1216/*
1217 * qla2x00_get_port_database
1218 * Issue normal/enhanced get port database mailbox command
1219 * and copy device name as necessary.
1220 *
1221 * Input:
1222 * ha = adapter state pointer.
1223 * dev = structure pointer.
1224 * opt = enhanced cmd option byte.
1225 *
1226 * Returns:
1227 * qla2x00 local function return status code.
1228 *
1229 * Context:
1230 * Kernel context.
1231 */
1232int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001233qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234{
1235 int rval;
1236 mbx_cmd_t mc;
1237 mbx_cmd_t *mcp = &mc;
1238 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001239 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001241 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001243 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001245 pd24 = NULL;
1246 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001248 ql_log(ql_log_warn, vha, 0x1050,
1249 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 return QLA_MEMORY_ALLOC_FAILED;
1251 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001252 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001254 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001255 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257 mcp->mb[2] = MSW(pd_dma);
1258 mcp->mb[3] = LSW(pd_dma);
1259 mcp->mb[6] = MSW(MSD(pd_dma));
1260 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001261 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001262 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001264 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001265 mcp->mb[1] = fcport->loop_id;
1266 mcp->mb[10] = opt;
1267 mcp->out_mb |= MBX_10|MBX_1;
1268 mcp->in_mb |= MBX_1;
1269 } else if (HAS_EXTENDED_IDS(ha)) {
1270 mcp->mb[1] = fcport->loop_id;
1271 mcp->mb[10] = opt;
1272 mcp->out_mb |= MBX_10|MBX_1;
1273 } else {
1274 mcp->mb[1] = fcport->loop_id << 8 | opt;
1275 mcp->out_mb |= MBX_1;
1276 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001277 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1278 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 mcp->flags = MBX_DMA_IN;
1280 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001281 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 if (rval != QLA_SUCCESS)
1283 goto gpd_error_out;
1284
Andrew Vasqueze4289242007-07-19 15:05:56 -07001285 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001286 pd24 = (struct port_database_24xx *) pd;
1287
1288 /* Check for logged in state. */
1289 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1290 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001291 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1292 "Unable to verify login-state (%x/%x) for "
1293 "loop_id %x.\n", pd24->current_login_state,
1294 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001295 rval = QLA_FUNCTION_FAILED;
1296 goto gpd_error_out;
1297 }
1298
1299 /* Names are little-endian. */
1300 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1301 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1302
1303 /* Get port_id of device. */
1304 fcport->d_id.b.domain = pd24->port_id[0];
1305 fcport->d_id.b.area = pd24->port_id[1];
1306 fcport->d_id.b.al_pa = pd24->port_id[2];
1307 fcport->d_id.b.rsvd_1 = 0;
1308
1309 /* If not target must be initiator or unknown type. */
1310 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1311 fcport->port_type = FCT_INITIATOR;
1312 else
1313 fcport->port_type = FCT_TARGET;
1314 } else {
1315 /* Check for logged in state. */
1316 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1317 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001318 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1319 "Unable to verify login-state (%x/%x) - "
1320 "portid=%02x%02x%02x.\n", pd->master_state,
1321 pd->slave_state, fcport->d_id.b.domain,
1322 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001323 rval = QLA_FUNCTION_FAILED;
1324 goto gpd_error_out;
1325 }
1326
1327 /* Names are little-endian. */
1328 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1329 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1330
1331 /* Get port_id of device. */
1332 fcport->d_id.b.domain = pd->port_id[0];
1333 fcport->d_id.b.area = pd->port_id[3];
1334 fcport->d_id.b.al_pa = pd->port_id[2];
1335 fcport->d_id.b.rsvd_1 = 0;
1336
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001337 /* If not target must be initiator or unknown type. */
1338 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1339 fcport->port_type = FCT_INITIATOR;
1340 else
1341 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001342
1343 /* Passback COS information. */
1344 fcport->supported_classes = (pd->options & BIT_4) ?
1345 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 }
1347
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348gpd_error_out:
1349 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1350
1351 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001352 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1353 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1354 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001356 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 }
1358
1359 return rval;
1360}
1361
1362/*
1363 * qla2x00_get_firmware_state
1364 * Get adapter firmware state.
1365 *
1366 * Input:
1367 * ha = adapter block pointer.
1368 * dptr = pointer for firmware state.
1369 * TARGET_QUEUE_LOCK must be released.
1370 * ADAPTER_STATE_LOCK must be released.
1371 *
1372 * Returns:
1373 * qla2x00 local function return status code.
1374 *
1375 * Context:
1376 * Kernel context.
1377 */
1378int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001379qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380{
1381 int rval;
1382 mbx_cmd_t mc;
1383 mbx_cmd_t *mcp = &mc;
1384
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001385 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
1387 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1388 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001389 if (IS_FWI2_CAPABLE(vha->hw))
1390 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1391 else
1392 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001393 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001395 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001397 /* Return firmware states. */
1398 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001399 if (IS_FWI2_CAPABLE(vha->hw)) {
1400 states[1] = mcp->mb[2];
1401 states[2] = mcp->mb[3];
1402 states[3] = mcp->mb[4];
1403 states[4] = mcp->mb[5];
1404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
1406 if (rval != QLA_SUCCESS) {
1407 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001408 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 } else {
1410 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001411 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 }
1413
1414 return rval;
1415}
1416
1417/*
1418 * qla2x00_get_port_name
1419 * Issue get port name mailbox command.
1420 * Returned name is in big endian format.
1421 *
1422 * Input:
1423 * ha = adapter block pointer.
1424 * loop_id = loop ID of device.
1425 * name = pointer for name.
1426 * TARGET_QUEUE_LOCK must be released.
1427 * ADAPTER_STATE_LOCK must be released.
1428 *
1429 * Returns:
1430 * qla2x00 local function return status code.
1431 *
1432 * Context:
1433 * Kernel context.
1434 */
1435int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001436qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 uint8_t opt)
1438{
1439 int rval;
1440 mbx_cmd_t mc;
1441 mbx_cmd_t *mcp = &mc;
1442
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001443 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
1445 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001446 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001447 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001448 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 mcp->mb[1] = loop_id;
1450 mcp->mb[10] = opt;
1451 mcp->out_mb |= MBX_10;
1452 } else {
1453 mcp->mb[1] = loop_id << 8 | opt;
1454 }
1455
1456 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001457 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001459 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
1461 if (rval != QLA_SUCCESS) {
1462 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001463 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 } else {
1465 if (name != NULL) {
1466 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001467 name[0] = MSB(mcp->mb[2]);
1468 name[1] = LSB(mcp->mb[2]);
1469 name[2] = MSB(mcp->mb[3]);
1470 name[3] = LSB(mcp->mb[3]);
1471 name[4] = MSB(mcp->mb[6]);
1472 name[5] = LSB(mcp->mb[6]);
1473 name[6] = MSB(mcp->mb[7]);
1474 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 }
1476
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001477 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 }
1479
1480 return rval;
1481}
1482
1483/*
1484 * qla2x00_lip_reset
1485 * Issue LIP reset mailbox command.
1486 *
1487 * Input:
1488 * ha = adapter block pointer.
1489 * TARGET_QUEUE_LOCK must be released.
1490 * ADAPTER_STATE_LOCK must be released.
1491 *
1492 * Returns:
1493 * qla2x00 local function return status code.
1494 *
1495 * Context:
1496 * Kernel context.
1497 */
1498int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001499qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500{
1501 int rval;
1502 mbx_cmd_t mc;
1503 mbx_cmd_t *mcp = &mc;
1504
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001505 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001507 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001508 /* Logout across all FCFs. */
1509 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1510 mcp->mb[1] = BIT_1;
1511 mcp->mb[2] = 0;
1512 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1513 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001514 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001515 mcp->mb[1] = BIT_6;
1516 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001517 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001518 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001520 mcp->mb[0] = MBC_LIP_RESET;
1521 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001522 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001523 mcp->mb[1] = 0x00ff;
1524 mcp->mb[10] = 0;
1525 mcp->out_mb |= MBX_10;
1526 } else {
1527 mcp->mb[1] = 0xff00;
1528 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001529 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001530 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001533 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001535 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 if (rval != QLA_SUCCESS) {
1538 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001539 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 } else {
1541 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001542 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 }
1544
1545 return rval;
1546}
1547
1548/*
1549 * qla2x00_send_sns
1550 * Send SNS command.
1551 *
1552 * Input:
1553 * ha = adapter block pointer.
1554 * sns = pointer for command.
1555 * cmd_size = command size.
1556 * buf_size = response/command size.
1557 * TARGET_QUEUE_LOCK must be released.
1558 * ADAPTER_STATE_LOCK must be released.
1559 *
1560 * Returns:
1561 * qla2x00 local function return status code.
1562 *
1563 * Context:
1564 * Kernel context.
1565 */
1566int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001567qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 uint16_t cmd_size, size_t buf_size)
1569{
1570 int rval;
1571 mbx_cmd_t mc;
1572 mbx_cmd_t *mcp = &mc;
1573
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001574 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001576 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1577 "Retry cnt=%d ratov=%d total tov=%d.\n",
1578 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1581 mcp->mb[1] = cmd_size;
1582 mcp->mb[2] = MSW(sns_phys_address);
1583 mcp->mb[3] = LSW(sns_phys_address);
1584 mcp->mb[6] = MSW(MSD(sns_phys_address));
1585 mcp->mb[7] = LSW(MSD(sns_phys_address));
1586 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1587 mcp->in_mb = MBX_0|MBX_1;
1588 mcp->buf_size = buf_size;
1589 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001590 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1591 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592
1593 if (rval != QLA_SUCCESS) {
1594 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001595 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1596 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1597 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 } else {
1599 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001600 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 }
1602
1603 return rval;
1604}
1605
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001606int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001607qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001608 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1609{
1610 int rval;
1611
1612 struct logio_entry_24xx *lg;
1613 dma_addr_t lg_dma;
1614 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001615 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001616 struct req_que *req;
1617 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001618
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001619 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001620
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001621 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001622 req = ha->req_q_map[0];
1623 else
1624 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001625 rsp = req->rsp;
1626
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001627 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1628 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001629 ql_log(ql_log_warn, vha, 0x1062,
1630 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001631 return QLA_MEMORY_ALLOC_FAILED;
1632 }
1633 memset(lg, 0, sizeof(struct logio_entry_24xx));
1634
1635 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1636 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001637 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001638 lg->nport_handle = cpu_to_le16(loop_id);
1639 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1640 if (opt & BIT_0)
1641 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001642 if (opt & BIT_1)
1643 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001644 lg->port_id[0] = al_pa;
1645 lg->port_id[1] = area;
1646 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001647 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001648 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1649 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001650 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001651 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1652 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001653 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001654 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1655 "Failed to complete IOCB -- error status (%x).\n",
1656 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001657 rval = QLA_FUNCTION_FAILED;
1658 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1659 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1660 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1661
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001662 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1663 "Failed to complete IOCB -- completion status (%x) "
1664 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1665 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001666
1667 switch (iop[0]) {
1668 case LSC_SCODE_PORTID_USED:
1669 mb[0] = MBS_PORT_ID_USED;
1670 mb[1] = LSW(iop[1]);
1671 break;
1672 case LSC_SCODE_NPORT_USED:
1673 mb[0] = MBS_LOOP_ID_USED;
1674 break;
1675 case LSC_SCODE_NOLINK:
1676 case LSC_SCODE_NOIOCB:
1677 case LSC_SCODE_NOXCB:
1678 case LSC_SCODE_CMD_FAILED:
1679 case LSC_SCODE_NOFABRIC:
1680 case LSC_SCODE_FW_NOT_READY:
1681 case LSC_SCODE_NOT_LOGGED_IN:
1682 case LSC_SCODE_NOPCB:
1683 case LSC_SCODE_ELS_REJECT:
1684 case LSC_SCODE_CMD_PARAM_ERR:
1685 case LSC_SCODE_NONPORT:
1686 case LSC_SCODE_LOGGED_IN:
1687 case LSC_SCODE_NOFLOGI_ACC:
1688 default:
1689 mb[0] = MBS_COMMAND_ERROR;
1690 break;
1691 }
1692 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001693 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001694
1695 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1696
1697 mb[0] = MBS_COMMAND_COMPLETE;
1698 mb[1] = 0;
1699 if (iop[0] & BIT_4) {
1700 if (iop[0] & BIT_8)
1701 mb[1] |= BIT_1;
1702 } else
1703 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001704
1705 /* Passback COS information. */
1706 mb[10] = 0;
1707 if (lg->io_parameter[7] || lg->io_parameter[8])
1708 mb[10] |= BIT_0; /* Class 2. */
1709 if (lg->io_parameter[9] || lg->io_parameter[10])
1710 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001711 }
1712
1713 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1714
1715 return rval;
1716}
1717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718/*
1719 * qla2x00_login_fabric
1720 * Issue login fabric port mailbox command.
1721 *
1722 * Input:
1723 * ha = adapter block pointer.
1724 * loop_id = device loop ID.
1725 * domain = device domain.
1726 * area = device area.
1727 * al_pa = device AL_PA.
1728 * status = pointer for return status.
1729 * opt = command options.
1730 * TARGET_QUEUE_LOCK must be released.
1731 * ADAPTER_STATE_LOCK must be released.
1732 *
1733 * Returns:
1734 * qla2x00 local function return status code.
1735 *
1736 * Context:
1737 * Kernel context.
1738 */
1739int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001740qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1742{
1743 int rval;
1744 mbx_cmd_t mc;
1745 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001746 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001748 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
1750 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1751 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1752 if (HAS_EXTENDED_IDS(ha)) {
1753 mcp->mb[1] = loop_id;
1754 mcp->mb[10] = opt;
1755 mcp->out_mb |= MBX_10;
1756 } else {
1757 mcp->mb[1] = (loop_id << 8) | opt;
1758 }
1759 mcp->mb[2] = domain;
1760 mcp->mb[3] = area << 8 | al_pa;
1761
1762 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1763 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1764 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001765 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
1767 /* Return mailbox statuses. */
1768 if (mb != NULL) {
1769 mb[0] = mcp->mb[0];
1770 mb[1] = mcp->mb[1];
1771 mb[2] = mcp->mb[2];
1772 mb[6] = mcp->mb[6];
1773 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001774 /* COS retrieved from Get-Port-Database mailbox command. */
1775 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 }
1777
1778 if (rval != QLA_SUCCESS) {
1779 /* RLU tmp code: need to change main mailbox_command function to
1780 * return ok even when the mailbox completion value is not
1781 * SUCCESS. The caller needs to be responsible to interpret
1782 * the return values of this mailbox command if we're not
1783 * to change too much of the existing code.
1784 */
1785 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1786 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1787 mcp->mb[0] == 0x4006)
1788 rval = QLA_SUCCESS;
1789
1790 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001791 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1792 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1793 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 } else {
1795 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001796 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 }
1798
1799 return rval;
1800}
1801
1802/*
1803 * qla2x00_login_local_device
1804 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001805 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 * Input:
1807 * ha = adapter block pointer.
1808 * loop_id = device loop ID.
1809 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001810 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 * Returns:
1812 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001813 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 * Context:
1815 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001816 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 */
1818int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001819qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 uint16_t *mb_ret, uint8_t opt)
1821{
1822 int rval;
1823 mbx_cmd_t mc;
1824 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001825 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001827 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1828
Andrew Vasqueze4289242007-07-19 15:05:56 -07001829 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001830 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001831 fcport->d_id.b.domain, fcport->d_id.b.area,
1832 fcport->d_id.b.al_pa, mb_ret, opt);
1833
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1835 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001836 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001838 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 mcp->mb[2] = opt;
1840 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1841 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1842 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1843 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001844 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
1846 /* Return mailbox statuses. */
1847 if (mb_ret != NULL) {
1848 mb_ret[0] = mcp->mb[0];
1849 mb_ret[1] = mcp->mb[1];
1850 mb_ret[6] = mcp->mb[6];
1851 mb_ret[7] = mcp->mb[7];
1852 }
1853
1854 if (rval != QLA_SUCCESS) {
1855 /* AV tmp code: need to change main mailbox_command function to
1856 * return ok even when the mailbox completion value is not
1857 * SUCCESS. The caller needs to be responsible to interpret
1858 * the return values of this mailbox command if we're not
1859 * to change too much of the existing code.
1860 */
1861 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1862 rval = QLA_SUCCESS;
1863
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001864 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1865 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1866 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 } else {
1868 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001869 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 }
1871
1872 return (rval);
1873}
1874
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001875int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001876qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001877 uint8_t area, uint8_t al_pa)
1878{
1879 int rval;
1880 struct logio_entry_24xx *lg;
1881 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001882 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001883 struct req_que *req;
1884 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001885
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001886 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001887
1888 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1889 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001890 ql_log(ql_log_warn, vha, 0x106e,
1891 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001892 return QLA_MEMORY_ALLOC_FAILED;
1893 }
1894 memset(lg, 0, sizeof(struct logio_entry_24xx));
1895
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001896 if (ql2xmaxqueues > 1)
1897 req = ha->req_q_map[0];
1898 else
1899 req = vha->req;
1900 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001901 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1902 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001903 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001904 lg->nport_handle = cpu_to_le16(loop_id);
1905 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001906 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1907 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001908 lg->port_id[0] = al_pa;
1909 lg->port_id[1] = area;
1910 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001911 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001912 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1913 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001914 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001915 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1916 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001917 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001918 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1919 "Failed to complete IOCB -- error status (%x).\n",
1920 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001921 rval = QLA_FUNCTION_FAILED;
1922 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001923 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1924 "Failed to complete IOCB -- completion status (%x) "
1925 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001926 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001927 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001928 } else {
1929 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001930 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001931 }
1932
1933 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1934
1935 return rval;
1936}
1937
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938/*
1939 * qla2x00_fabric_logout
1940 * Issue logout fabric port mailbox command.
1941 *
1942 * Input:
1943 * ha = adapter block pointer.
1944 * loop_id = device loop ID.
1945 * TARGET_QUEUE_LOCK must be released.
1946 * ADAPTER_STATE_LOCK must be released.
1947 *
1948 * Returns:
1949 * qla2x00 local function return status code.
1950 *
1951 * Context:
1952 * Kernel context.
1953 */
1954int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001955qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001956 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957{
1958 int rval;
1959 mbx_cmd_t mc;
1960 mbx_cmd_t *mcp = &mc;
1961
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001962 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
1964 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1965 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001966 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 mcp->mb[1] = loop_id;
1968 mcp->mb[10] = 0;
1969 mcp->out_mb |= MBX_10;
1970 } else {
1971 mcp->mb[1] = loop_id << 8;
1972 }
1973
1974 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001975 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001977 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979 if (rval != QLA_SUCCESS) {
1980 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001981 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1982 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 } else {
1984 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001985 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 }
1987
1988 return rval;
1989}
1990
1991/*
1992 * qla2x00_full_login_lip
1993 * Issue full login LIP mailbox command.
1994 *
1995 * Input:
1996 * ha = adapter block pointer.
1997 * TARGET_QUEUE_LOCK must be released.
1998 * ADAPTER_STATE_LOCK must be released.
1999 *
2000 * Returns:
2001 * qla2x00 local function return status code.
2002 *
2003 * Context:
2004 * Kernel context.
2005 */
2006int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002007qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008{
2009 int rval;
2010 mbx_cmd_t mc;
2011 mbx_cmd_t *mcp = &mc;
2012
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002013 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
2015 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002016 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002017 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 mcp->mb[3] = 0;
2019 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2020 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002021 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002023 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
2025 if (rval != QLA_SUCCESS) {
2026 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002027 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 } else {
2029 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002030 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 }
2032
2033 return rval;
2034}
2035
2036/*
2037 * qla2x00_get_id_list
2038 *
2039 * Input:
2040 * ha = adapter block pointer.
2041 *
2042 * Returns:
2043 * qla2x00 local function return status code.
2044 *
2045 * Context:
2046 * Kernel context.
2047 */
2048int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002049qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 uint16_t *entries)
2051{
2052 int rval;
2053 mbx_cmd_t mc;
2054 mbx_cmd_t *mcp = &mc;
2055
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002056 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057
2058 if (id_list == NULL)
2059 return QLA_FUNCTION_FAILED;
2060
2061 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002062 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002063 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002064 mcp->mb[2] = MSW(id_list_dma);
2065 mcp->mb[3] = LSW(id_list_dma);
2066 mcp->mb[6] = MSW(MSD(id_list_dma));
2067 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002068 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002069 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002070 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002071 } else {
2072 mcp->mb[1] = MSW(id_list_dma);
2073 mcp->mb[2] = LSW(id_list_dma);
2074 mcp->mb[3] = MSW(MSD(id_list_dma));
2075 mcp->mb[6] = LSW(MSD(id_list_dma));
2076 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002079 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002081 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
2083 if (rval != QLA_SUCCESS) {
2084 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002085 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 } else {
2087 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002088 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 }
2090
2091 return rval;
2092}
2093
2094/*
2095 * qla2x00_get_resource_cnts
2096 * Get current firmware resource counts.
2097 *
2098 * Input:
2099 * ha = adapter block pointer.
2100 *
2101 * Returns:
2102 * qla2x00 local function return status code.
2103 *
2104 * Context:
2105 * Kernel context.
2106 */
2107int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002108qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002109 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002110 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002111{
2112 int rval;
2113 mbx_cmd_t mc;
2114 mbx_cmd_t *mcp = &mc;
2115
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002116 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
2118 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2119 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002120 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002121 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002122 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002123 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002125 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126
2127 if (rval != QLA_SUCCESS) {
2128 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002129 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2130 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002132 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2133 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2134 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2135 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2136 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 if (cur_xchg_cnt)
2139 *cur_xchg_cnt = mcp->mb[3];
2140 if (orig_xchg_cnt)
2141 *orig_xchg_cnt = mcp->mb[6];
2142 if (cur_iocb_cnt)
2143 *cur_iocb_cnt = mcp->mb[7];
2144 if (orig_iocb_cnt)
2145 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002146 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002147 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002148 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002149 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 }
2151
2152 return (rval);
2153}
2154
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155/*
2156 * qla2x00_get_fcal_position_map
2157 * Get FCAL (LILP) position map using mailbox command
2158 *
2159 * Input:
2160 * ha = adapter state pointer.
2161 * pos_map = buffer pointer (can be NULL).
2162 *
2163 * Returns:
2164 * qla2x00 local function return status code.
2165 *
2166 * Context:
2167 * Kernel context.
2168 */
2169int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002170qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171{
2172 int rval;
2173 mbx_cmd_t mc;
2174 mbx_cmd_t *mcp = &mc;
2175 char *pmap;
2176 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002177 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002179 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2180
Andrew Vasquez4b892582008-09-11 21:22:48 -07002181 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002183 ql_log(ql_log_warn, vha, 0x1080,
2184 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185 return QLA_MEMORY_ALLOC_FAILED;
2186 }
2187 memset(pmap, 0, FCAL_MAP_SIZE);
2188
2189 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2190 mcp->mb[2] = MSW(pmap_dma);
2191 mcp->mb[3] = LSW(pmap_dma);
2192 mcp->mb[6] = MSW(MSD(pmap_dma));
2193 mcp->mb[7] = LSW(MSD(pmap_dma));
2194 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2195 mcp->in_mb = MBX_1|MBX_0;
2196 mcp->buf_size = FCAL_MAP_SIZE;
2197 mcp->flags = MBX_DMA_IN;
2198 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002199 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200
2201 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002202 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2203 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2204 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2205 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2206 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207
2208 if (pos_map)
2209 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2210 }
2211 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2212
2213 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002214 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002216 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 }
2218
2219 return rval;
2220}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002221
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002222/*
2223 * qla2x00_get_link_status
2224 *
2225 * Input:
2226 * ha = adapter block pointer.
2227 * loop_id = device loop ID.
2228 * ret_buf = pointer to link status return buffer.
2229 *
2230 * Returns:
2231 * 0 = success.
2232 * BIT_0 = mem alloc error.
2233 * BIT_1 = mailbox error.
2234 */
2235int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002236qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002237 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002238{
2239 int rval;
2240 mbx_cmd_t mc;
2241 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002242 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002243 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002244
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002245 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002246
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002247 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002248 mcp->mb[2] = MSW(stats_dma);
2249 mcp->mb[3] = LSW(stats_dma);
2250 mcp->mb[6] = MSW(MSD(stats_dma));
2251 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002252 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2253 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002254 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002255 mcp->mb[1] = loop_id;
2256 mcp->mb[4] = 0;
2257 mcp->mb[10] = 0;
2258 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2259 mcp->in_mb |= MBX_1;
2260 } else if (HAS_EXTENDED_IDS(ha)) {
2261 mcp->mb[1] = loop_id;
2262 mcp->mb[10] = 0;
2263 mcp->out_mb |= MBX_10|MBX_1;
2264 } else {
2265 mcp->mb[1] = loop_id << 8;
2266 mcp->out_mb |= MBX_1;
2267 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002268 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002269 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002270 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002271
2272 if (rval == QLA_SUCCESS) {
2273 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002274 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2275 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002276 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002277 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002278 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002279 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002280 dwords = offsetof(struct link_statistics, unused1) / 4;
2281 siter = diter = &stats->link_fail_cnt;
2282 while (dwords--)
2283 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002284 }
2285 } else {
2286 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002287 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002288 }
2289
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002290 return rval;
2291}
2292
2293int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002294qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002295 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002296{
2297 int rval;
2298 mbx_cmd_t mc;
2299 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002300 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002301
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002302 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002303
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002304 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002305 mcp->mb[2] = MSW(stats_dma);
2306 mcp->mb[3] = LSW(stats_dma);
2307 mcp->mb[6] = MSW(MSD(stats_dma));
2308 mcp->mb[7] = LSW(MSD(stats_dma));
2309 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002310 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002311 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002312 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002313 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002314 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002315 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002316 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002317
2318 if (rval == QLA_SUCCESS) {
2319 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002320 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2321 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002322 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002323 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002324 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002325 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002326 dwords = sizeof(struct link_statistics) / 4;
2327 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002328 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002329 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002330 }
2331 } else {
2332 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002333 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334 }
2335
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002336 return rval;
2337}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002338
2339int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002340qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002341{
2342 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002343 unsigned long flags = 0;
2344
2345 struct abort_entry_24xx *abt;
2346 dma_addr_t abt_dma;
2347 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002348 fc_port_t *fcport = sp->fcport;
2349 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002350 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002351 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002352
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002353 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002354
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002355 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002356 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002357 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002358 break;
2359 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002360 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002361 if (handle == MAX_OUTSTANDING_COMMANDS) {
2362 /* Command not found. */
2363 return QLA_FUNCTION_FAILED;
2364 }
2365
2366 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2367 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002368 ql_log(ql_log_warn, vha, 0x108d,
2369 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002370 return QLA_MEMORY_ALLOC_FAILED;
2371 }
2372 memset(abt, 0, sizeof(struct abort_entry_24xx));
2373
2374 abt->entry_type = ABORT_IOCB_TYPE;
2375 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002376 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002377 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002378 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002379 abt->port_id[0] = fcport->d_id.b.al_pa;
2380 abt->port_id[1] = fcport->d_id.b.area;
2381 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002382 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002383
2384 abt->req_que_no = cpu_to_le16(req->id);
2385
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002386 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002387 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002388 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2389 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002390 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002391 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2392 "Failed to complete IOCB -- error status (%x).\n",
2393 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002394 rval = QLA_FUNCTION_FAILED;
2395 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002396 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2397 "Failed to complete IOCB -- completion status (%x).\n",
2398 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002399 rval = QLA_FUNCTION_FAILED;
2400 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002401 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002402 }
2403
2404 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2405
2406 return rval;
2407}
2408
2409struct tsk_mgmt_cmd {
2410 union {
2411 struct tsk_mgmt_entry tsk;
2412 struct sts_entry_24xx sts;
2413 } p;
2414};
2415
Andrew Vasquez523ec772008-04-03 13:13:24 -07002416static int
2417__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002418 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002419{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002420 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002421 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002422 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002423 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002424 scsi_qla_host_t *vha;
2425 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002426 struct req_que *req;
2427 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002428
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002429 vha = fcport->vha;
2430 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002431 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002432
2433 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2434
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002435 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002436 rsp = ha->rsp_q_map[tag + 1];
2437 else
2438 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002439 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002440 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002441 ql_log(ql_log_warn, vha, 0x1093,
2442 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002443 return QLA_MEMORY_ALLOC_FAILED;
2444 }
2445 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2446
2447 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2448 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002449 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002450 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002451 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002452 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002453 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2454 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2455 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002456 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002457 if (type == TCF_LUN_RESET) {
2458 int_to_scsilun(l, &tsk->p.tsk.lun);
2459 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2460 sizeof(tsk->p.tsk.lun));
2461 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002462
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002463 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002464 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002465 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002466 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2467 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002468 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002469 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2470 "Failed to complete IOCB -- error status (%x).\n",
2471 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002472 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002473 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002474 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002475 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2476 "Failed to complete IOCB -- completion status (%x).\n",
2477 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002478 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002479 } else if (le16_to_cpu(sts->scsi_status) &
2480 SS_RESPONSE_INFO_LEN_VALID) {
2481 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002482 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2483 "Ignoring inconsistent data length -- not enough "
2484 "response info (%d).\n",
2485 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002486 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002487 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2488 "Failed to complete IOCB -- response (%x).\n",
2489 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002490 rval = QLA_FUNCTION_FAILED;
2491 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002492 }
2493
2494 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002495 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002496 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2497 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002498 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2499 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002500 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002501 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002502 }
2503
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002504 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002505
2506 return rval;
2507}
2508
Andrew Vasquez523ec772008-04-03 13:13:24 -07002509int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002510qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002511{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002512 struct qla_hw_data *ha = fcport->vha->hw;
2513
2514 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2515 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2516
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002517 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002518}
2519
2520int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002521qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002522{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002523 struct qla_hw_data *ha = fcport->vha->hw;
2524
2525 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2526 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2527
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002528 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002529}
2530
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002531int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002532qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002533{
2534 int rval;
2535 mbx_cmd_t mc;
2536 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002537 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002538
Andrew Vasquez68af0812008-05-12 22:21:13 -07002539 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002540 return QLA_FUNCTION_FAILED;
2541
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002542 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002543
2544 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2545 mcp->out_mb = MBX_0;
2546 mcp->in_mb = MBX_0;
2547 mcp->tov = 5;
2548 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002549 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002550
2551 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002552 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002553 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002554 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002555 }
2556
2557 return rval;
2558}
2559
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002560/**
2561 * qla2x00_set_serdes_params() -
2562 * @ha: HA context
2563 *
2564 * Returns
2565 */
2566int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002567qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002568 uint16_t sw_em_2g, uint16_t sw_em_4g)
2569{
2570 int rval;
2571 mbx_cmd_t mc;
2572 mbx_cmd_t *mcp = &mc;
2573
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002574 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002575
2576 mcp->mb[0] = MBC_SERDES_PARAMS;
2577 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002578 mcp->mb[2] = sw_em_1g | BIT_15;
2579 mcp->mb[3] = sw_em_2g | BIT_15;
2580 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002581 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2582 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002583 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002584 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002585 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002586
2587 if (rval != QLA_SUCCESS) {
2588 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002589 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2590 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002591 } else {
2592 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002593 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002594 }
2595
2596 return rval;
2597}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002598
2599int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002600qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002601{
2602 int rval;
2603 mbx_cmd_t mc;
2604 mbx_cmd_t *mcp = &mc;
2605
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002606 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002607 return QLA_FUNCTION_FAILED;
2608
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002609 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002610
2611 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002612 mcp->mb[1] = 0;
2613 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002614 mcp->in_mb = MBX_0;
2615 mcp->tov = 5;
2616 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002617 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002618
2619 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002620 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002621 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2622 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002623 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002624 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002625 }
2626
2627 return rval;
2628}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002629
2630int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002631qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002632 uint16_t buffers)
2633{
2634 int rval;
2635 mbx_cmd_t mc;
2636 mbx_cmd_t *mcp = &mc;
2637
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002638 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2639
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002640 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002641 return QLA_FUNCTION_FAILED;
2642
Andrew Vasquez85880802009-12-15 21:29:46 -08002643 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2644 return QLA_FUNCTION_FAILED;
2645
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002646 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002647 mcp->mb[1] = TC_EFT_ENABLE;
2648 mcp->mb[2] = LSW(eft_dma);
2649 mcp->mb[3] = MSW(eft_dma);
2650 mcp->mb[4] = LSW(MSD(eft_dma));
2651 mcp->mb[5] = MSW(MSD(eft_dma));
2652 mcp->mb[6] = buffers;
2653 mcp->mb[7] = TC_AEN_DISABLE;
2654 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002655 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002656 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002657 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002658 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002659 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002660 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2661 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2662 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002663 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002664 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002665 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002666
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002667 return rval;
2668}
2669
2670int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002671qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002672{
2673 int rval;
2674 mbx_cmd_t mc;
2675 mbx_cmd_t *mcp = &mc;
2676
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002677 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2678
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002679 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002680 return QLA_FUNCTION_FAILED;
2681
Andrew Vasquez85880802009-12-15 21:29:46 -08002682 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2683 return QLA_FUNCTION_FAILED;
2684
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002685 mcp->mb[0] = MBC_TRACE_CONTROL;
2686 mcp->mb[1] = TC_EFT_DISABLE;
2687 mcp->out_mb = MBX_1|MBX_0;
2688 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002689 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002690 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002691 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002692 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002693 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2694 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2695 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002696 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002697 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002698 }
2699
2700 return rval;
2701}
2702
Andrew Vasquez88729e52006-06-23 16:10:50 -07002703int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002704qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002705 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2706{
2707 int rval;
2708 mbx_cmd_t mc;
2709 mbx_cmd_t *mcp = &mc;
2710
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002711 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2712
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002713 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2714 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002715 return QLA_FUNCTION_FAILED;
2716
Andrew Vasquez85880802009-12-15 21:29:46 -08002717 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2718 return QLA_FUNCTION_FAILED;
2719
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002720 mcp->mb[0] = MBC_TRACE_CONTROL;
2721 mcp->mb[1] = TC_FCE_ENABLE;
2722 mcp->mb[2] = LSW(fce_dma);
2723 mcp->mb[3] = MSW(fce_dma);
2724 mcp->mb[4] = LSW(MSD(fce_dma));
2725 mcp->mb[5] = MSW(MSD(fce_dma));
2726 mcp->mb[6] = buffers;
2727 mcp->mb[7] = TC_AEN_DISABLE;
2728 mcp->mb[8] = 0;
2729 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2730 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2731 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2732 MBX_1|MBX_0;
2733 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002734 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002735 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002736 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002737 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002738 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2739 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2740 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002741 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002742 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002743
2744 if (mb)
2745 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2746 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002747 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002748 }
2749
2750 return rval;
2751}
2752
2753int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002754qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002755{
2756 int rval;
2757 mbx_cmd_t mc;
2758 mbx_cmd_t *mcp = &mc;
2759
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002760 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2761
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002762 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002763 return QLA_FUNCTION_FAILED;
2764
Andrew Vasquez85880802009-12-15 21:29:46 -08002765 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2766 return QLA_FUNCTION_FAILED;
2767
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002768 mcp->mb[0] = MBC_TRACE_CONTROL;
2769 mcp->mb[1] = TC_FCE_DISABLE;
2770 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2771 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2772 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2773 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002774 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002775 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002776 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002777 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002778 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2779 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2780 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002781 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002782 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002783
2784 if (wr)
2785 *wr = (uint64_t) mcp->mb[5] << 48 |
2786 (uint64_t) mcp->mb[4] << 32 |
2787 (uint64_t) mcp->mb[3] << 16 |
2788 (uint64_t) mcp->mb[2];
2789 if (rd)
2790 *rd = (uint64_t) mcp->mb[9] << 48 |
2791 (uint64_t) mcp->mb[8] << 32 |
2792 (uint64_t) mcp->mb[7] << 16 |
2793 (uint64_t) mcp->mb[6];
2794 }
2795
2796 return rval;
2797}
2798
2799int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002800qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2801 uint16_t *port_speed, uint16_t *mb)
2802{
2803 int rval;
2804 mbx_cmd_t mc;
2805 mbx_cmd_t *mcp = &mc;
2806
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002807 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2808
Giridhar Malavali6e980162010-03-19 17:03:58 -07002809 if (!IS_IIDMA_CAPABLE(vha->hw))
2810 return QLA_FUNCTION_FAILED;
2811
Giridhar Malavali6e980162010-03-19 17:03:58 -07002812 mcp->mb[0] = MBC_PORT_PARAMS;
2813 mcp->mb[1] = loop_id;
2814 mcp->mb[2] = mcp->mb[3] = 0;
2815 mcp->mb[9] = vha->vp_idx;
2816 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2817 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2818 mcp->tov = MBX_TOV_SECONDS;
2819 mcp->flags = 0;
2820 rval = qla2x00_mailbox_command(vha, mcp);
2821
2822 /* Return mailbox statuses. */
2823 if (mb != NULL) {
2824 mb[0] = mcp->mb[0];
2825 mb[1] = mcp->mb[1];
2826 mb[3] = mcp->mb[3];
2827 }
2828
2829 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002830 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002831 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002832 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002833 if (port_speed)
2834 *port_speed = mcp->mb[3];
2835 }
2836
2837 return rval;
2838}
2839
2840int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002841qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002842 uint16_t port_speed, uint16_t *mb)
2843{
2844 int rval;
2845 mbx_cmd_t mc;
2846 mbx_cmd_t *mcp = &mc;
2847
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002848 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2849
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002850 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002851 return QLA_FUNCTION_FAILED;
2852
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002853 mcp->mb[0] = MBC_PORT_PARAMS;
2854 mcp->mb[1] = loop_id;
2855 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002856 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002857 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2858 else
2859 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2860 mcp->mb[9] = vha->vp_idx;
2861 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2862 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002863 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002864 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002865 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002866
2867 /* Return mailbox statuses. */
2868 if (mb != NULL) {
2869 mb[0] = mcp->mb[0];
2870 mb[1] = mcp->mb[1];
2871 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002872 }
2873
2874 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002875 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002876 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002877 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002878 }
2879
2880 return rval;
2881}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002882
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002883void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002884qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002885 struct vp_rpt_id_entry_24xx *rptid_entry)
2886{
2887 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002888 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002889 struct qla_hw_data *ha = vha->hw;
2890 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002891 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002892
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002893 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2894
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002895 if (rptid_entry->entry_status != 0)
2896 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002897
2898 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002899 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2900 "Format 0 : Number of VPs setup %d, number of "
2901 "VPs acquired %d.\n",
2902 MSB(le16_to_cpu(rptid_entry->vp_count)),
2903 LSB(le16_to_cpu(rptid_entry->vp_count)));
2904 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2905 "Primary port id %02x%02x%02x.\n",
2906 rptid_entry->port_id[2], rptid_entry->port_id[1],
2907 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002908 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002909 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002910 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2911 "Format 1: VP[%d] enabled - status %d - with "
2912 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002913 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002914 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002915
2916 vp = vha;
2917 if (vp_idx == 0 && (MSB(stat) != 1))
2918 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002919
Giridhar Malavali882a9172011-11-18 09:03:12 -08002920 if (MSB(stat) != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002921 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2922 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002923 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002924 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002925
Arun Easifeafb7b2010-09-03 14:57:00 -07002926 spin_lock_irqsave(&ha->vport_slock, flags);
2927 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002928 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002929 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002930 spin_unlock_irqrestore(&ha->vport_slock, flags);
2931
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002932 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002933 return;
2934
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002935 vp->d_id.b.domain = rptid_entry->port_id[2];
2936 vp->d_id.b.area = rptid_entry->port_id[1];
2937 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002938
2939 /*
2940 * Cannot configure here as we are still sitting on the
2941 * response queue. Handle it in dpc context.
2942 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002943 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002944
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002945reg_needed:
2946 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2947 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2948 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002949 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002950 }
2951}
2952
2953/*
2954 * qla24xx_modify_vp_config
2955 * Change VP configuration for vha
2956 *
2957 * Input:
2958 * vha = adapter block pointer.
2959 *
2960 * Returns:
2961 * qla2xxx local function return status code.
2962 *
2963 * Context:
2964 * Kernel context.
2965 */
2966int
2967qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2968{
2969 int rval;
2970 struct vp_config_entry_24xx *vpmod;
2971 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002972 struct qla_hw_data *ha = vha->hw;
2973 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002974
2975 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002976
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002977 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2978
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002979 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002980 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002981 ql_log(ql_log_warn, vha, 0x10bc,
2982 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002983 return QLA_MEMORY_ALLOC_FAILED;
2984 }
2985
2986 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2987 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2988 vpmod->entry_count = 1;
2989 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2990 vpmod->vp_count = 1;
2991 vpmod->vp_index1 = vha->vp_idx;
2992 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2993 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2994 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2995 vpmod->entry_count = 1;
2996
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002997 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002998 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002999 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3000 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003001 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003002 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3003 "Failed to complete IOCB -- error status (%x).\n",
3004 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003005 rval = QLA_FUNCTION_FAILED;
3006 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003007 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3008 "Failed to complete IOCB -- completion status (%x).\n",
3009 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003010 rval = QLA_FUNCTION_FAILED;
3011 } else {
3012 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003013 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003014 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3015 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003016 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003017
3018 return rval;
3019}
3020
3021/*
3022 * qla24xx_control_vp
3023 * Enable a virtual port for given host
3024 *
3025 * Input:
3026 * ha = adapter block pointer.
3027 * vhba = virtual adapter (unused)
3028 * index = index number for enabled VP
3029 *
3030 * Returns:
3031 * qla2xxx local function return status code.
3032 *
3033 * Context:
3034 * Kernel context.
3035 */
3036int
3037qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3038{
3039 int rval;
3040 int map, pos;
3041 struct vp_ctrl_entry_24xx *vce;
3042 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003043 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003044 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003045 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003046
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003047 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3048 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003049
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003050 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003051 return QLA_PARAMETER_ERROR;
3052
3053 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3054 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003055 ql_log(ql_log_warn, vha, 0x10c2,
3056 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003057 return QLA_MEMORY_ALLOC_FAILED;
3058 }
3059 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3060
3061 vce->entry_type = VP_CTRL_IOCB_TYPE;
3062 vce->entry_count = 1;
3063 vce->command = cpu_to_le16(cmd);
3064 vce->vp_count = __constant_cpu_to_le16(1);
3065
3066 /* index map in firmware starts with 1; decrement index
3067 * this is ok as we never use index 0
3068 */
3069 map = (vp_index - 1) / 8;
3070 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003071 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003072 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003073 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003074
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003075 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003076 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003077 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3078 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003079 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003080 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3081 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003082 vce->entry_status);
3083 rval = QLA_FUNCTION_FAILED;
3084 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003085 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3086 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003087 le16_to_cpu(vce->comp_status));
3088 rval = QLA_FUNCTION_FAILED;
3089 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003090 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003091 }
3092
3093 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3094
3095 return rval;
3096}
3097
3098/*
3099 * qla2x00_send_change_request
3100 * Receive or disable RSCN request from fabric controller
3101 *
3102 * Input:
3103 * ha = adapter block pointer
3104 * format = registration format:
3105 * 0 - Reserved
3106 * 1 - Fabric detected registration
3107 * 2 - N_port detected registration
3108 * 3 - Full registration
3109 * FF - clear registration
3110 * vp_idx = Virtual port index
3111 *
3112 * Returns:
3113 * qla2x00 local function return status code.
3114 *
3115 * Context:
3116 * Kernel Context
3117 */
3118
3119int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003120qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003121 uint16_t vp_idx)
3122{
3123 int rval;
3124 mbx_cmd_t mc;
3125 mbx_cmd_t *mcp = &mc;
3126
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003127 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3128
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003129 /*
3130 * This command is implicitly executed by firmware during login for the
3131 * physical hosts
3132 */
3133 if (vp_idx == 0)
3134 return QLA_FUNCTION_FAILED;
3135
3136 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3137 mcp->mb[1] = format;
3138 mcp->mb[9] = vp_idx;
3139 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3140 mcp->in_mb = MBX_0|MBX_1;
3141 mcp->tov = MBX_TOV_SECONDS;
3142 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003143 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003144
3145 if (rval == QLA_SUCCESS) {
3146 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3147 rval = BIT_1;
3148 }
3149 } else
3150 rval = BIT_1;
3151
3152 return rval;
3153}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003154
3155int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003156qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003157 uint32_t size)
3158{
3159 int rval;
3160 mbx_cmd_t mc;
3161 mbx_cmd_t *mcp = &mc;
3162
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003163 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003164
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003165 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003166 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3167 mcp->mb[8] = MSW(addr);
3168 mcp->out_mb = MBX_8|MBX_0;
3169 } else {
3170 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3171 mcp->out_mb = MBX_0;
3172 }
3173 mcp->mb[1] = LSW(addr);
3174 mcp->mb[2] = MSW(req_dma);
3175 mcp->mb[3] = LSW(req_dma);
3176 mcp->mb[6] = MSW(MSD(req_dma));
3177 mcp->mb[7] = LSW(MSD(req_dma));
3178 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003179 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003180 mcp->mb[4] = MSW(size);
3181 mcp->mb[5] = LSW(size);
3182 mcp->out_mb |= MBX_5|MBX_4;
3183 } else {
3184 mcp->mb[4] = LSW(size);
3185 mcp->out_mb |= MBX_4;
3186 }
3187
3188 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003189 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003190 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003191 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003192
3193 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003194 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3195 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003196 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003197 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003198 }
3199
3200 return rval;
3201}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003202
3203/* 84XX Support **************************************************************/
3204
3205struct cs84xx_mgmt_cmd {
3206 union {
3207 struct verify_chip_entry_84xx req;
3208 struct verify_chip_rsp_84xx rsp;
3209 } p;
3210};
3211
3212int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003213qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003214{
3215 int rval, retry;
3216 struct cs84xx_mgmt_cmd *mn;
3217 dma_addr_t mn_dma;
3218 uint16_t options;
3219 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003220 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003221
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003222 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003223
3224 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3225 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003226 return QLA_MEMORY_ALLOC_FAILED;
3227 }
3228
3229 /* Force Update? */
3230 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3231 /* Diagnostic firmware? */
3232 /* options |= MENLO_DIAG_FW; */
3233 /* We update the firmware with only one data sequence. */
3234 options |= VCO_END_OF_DATA;
3235
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003236 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003237 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003238 memset(mn, 0, sizeof(*mn));
3239 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3240 mn->p.req.entry_count = 1;
3241 mn->p.req.options = cpu_to_le16(options);
3242
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003243 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3244 "Dump of Verify Request.\n");
3245 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3246 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003247
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003248 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003249 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003250 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3251 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003252 goto verify_done;
3253 }
3254
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003255 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3256 "Dump of Verify Response.\n");
3257 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3258 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003259
3260 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3261 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3262 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003263 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3264 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003265
3266 if (status[0] != CS_COMPLETE) {
3267 rval = QLA_FUNCTION_FAILED;
3268 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003269 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3270 "Firmware update failed. Retrying "
3271 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003272 options |= VCO_DONT_UPDATE_FW;
3273 options &= ~VCO_FORCE_UPDATE;
3274 retry = 1;
3275 }
3276 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003277 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3278 "Firmware updated to %x.\n",
3279 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003280
3281 /* NOTE: we only update OP firmware. */
3282 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3283 ha->cs84xx->op_fw_version =
3284 le32_to_cpu(mn->p.rsp.fw_ver);
3285 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3286 flags);
3287 }
3288 } while (retry);
3289
3290verify_done:
3291 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3292
3293 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003294 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003295 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003296 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003297 }
3298
3299 return rval;
3300}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003301
3302int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003303qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003304{
3305 int rval;
3306 unsigned long flags;
3307 mbx_cmd_t mc;
3308 mbx_cmd_t *mcp = &mc;
3309 struct device_reg_25xxmq __iomem *reg;
3310 struct qla_hw_data *ha = vha->hw;
3311
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003312 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3313
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003314 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003315 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003316 mcp->mb[2] = MSW(LSD(req->dma));
3317 mcp->mb[3] = LSW(LSD(req->dma));
3318 mcp->mb[6] = MSW(MSD(req->dma));
3319 mcp->mb[7] = LSW(MSD(req->dma));
3320 mcp->mb[5] = req->length;
3321 if (req->rsp)
3322 mcp->mb[10] = req->rsp->id;
3323 mcp->mb[12] = req->qos;
3324 mcp->mb[11] = req->vp_idx;
3325 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003326 if (IS_QLA83XX(ha))
3327 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003328
3329 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3330 QLA_QUE_PAGE * req->id);
3331
3332 mcp->mb[4] = req->id;
3333 /* que in ptr index */
3334 mcp->mb[8] = 0;
3335 /* que out ptr index */
3336 mcp->mb[9] = 0;
3337 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3338 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3339 mcp->in_mb = MBX_0;
3340 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003341 mcp->tov = MBX_TOV_SECONDS * 2;
3342
3343 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3344 mcp->in_mb |= MBX_1;
3345 if (IS_QLA83XX(ha)) {
3346 mcp->out_mb |= MBX_15;
3347 /* debug q create issue in SR-IOV */
3348 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3349 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003350
3351 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003352 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003353 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003354 if (!IS_QLA83XX(ha))
3355 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003356 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003357 req->req_q_in = &reg->req_q_in;
3358 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003359 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3360
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003361 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003362 if (rval != QLA_SUCCESS) {
3363 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3364 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3365 } else {
3366 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3367 }
3368
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003369 return rval;
3370}
3371
3372int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003373qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003374{
3375 int rval;
3376 unsigned long flags;
3377 mbx_cmd_t mc;
3378 mbx_cmd_t *mcp = &mc;
3379 struct device_reg_25xxmq __iomem *reg;
3380 struct qla_hw_data *ha = vha->hw;
3381
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003382 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3383
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003384 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003385 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003386 mcp->mb[2] = MSW(LSD(rsp->dma));
3387 mcp->mb[3] = LSW(LSD(rsp->dma));
3388 mcp->mb[6] = MSW(MSD(rsp->dma));
3389 mcp->mb[7] = LSW(MSD(rsp->dma));
3390 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003391 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003392 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003393 if (IS_QLA83XX(ha))
3394 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003395
3396 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3397 QLA_QUE_PAGE * rsp->id);
3398
3399 mcp->mb[4] = rsp->id;
3400 /* que in ptr index */
3401 mcp->mb[8] = 0;
3402 /* que out ptr index */
3403 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003404 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003405 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3406 mcp->in_mb = MBX_0;
3407 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003408 mcp->tov = MBX_TOV_SECONDS * 2;
3409
3410 if (IS_QLA81XX(ha)) {
3411 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3412 mcp->in_mb |= MBX_1;
3413 } else if (IS_QLA83XX(ha)) {
3414 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3415 mcp->in_mb |= MBX_1;
3416 /* debug q create issue in SR-IOV */
3417 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3418 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003419
3420 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003421 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003422 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003423 if (!IS_QLA83XX(ha))
3424 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003425 }
3426
3427 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3428
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003429 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003430 if (rval != QLA_SUCCESS) {
3431 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3432 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3433 } else {
3434 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3435 }
3436
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003437 return rval;
3438}
3439
Andrew Vasquez8a659572009-02-08 20:50:12 -08003440int
3441qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3442{
3443 int rval;
3444 mbx_cmd_t mc;
3445 mbx_cmd_t *mcp = &mc;
3446
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003447 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003448
3449 mcp->mb[0] = MBC_IDC_ACK;
3450 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3451 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3452 mcp->in_mb = MBX_0;
3453 mcp->tov = MBX_TOV_SECONDS;
3454 mcp->flags = 0;
3455 rval = qla2x00_mailbox_command(vha, mcp);
3456
3457 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003458 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3459 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003460 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003461 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003462 }
3463
3464 return rval;
3465}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003466
3467int
3468qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3469{
3470 int rval;
3471 mbx_cmd_t mc;
3472 mbx_cmd_t *mcp = &mc;
3473
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003474 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3475
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003476 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003477 return QLA_FUNCTION_FAILED;
3478
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003479 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3480 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3481 mcp->out_mb = MBX_1|MBX_0;
3482 mcp->in_mb = MBX_1|MBX_0;
3483 mcp->tov = MBX_TOV_SECONDS;
3484 mcp->flags = 0;
3485 rval = qla2x00_mailbox_command(vha, mcp);
3486
3487 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003488 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3489 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3490 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003491 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003492 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003493 *sector_size = mcp->mb[1];
3494 }
3495
3496 return rval;
3497}
3498
3499int
3500qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3501{
3502 int rval;
3503 mbx_cmd_t mc;
3504 mbx_cmd_t *mcp = &mc;
3505
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003506 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003507 return QLA_FUNCTION_FAILED;
3508
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003509 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003510
3511 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3512 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3513 FAC_OPT_CMD_WRITE_PROTECT;
3514 mcp->out_mb = MBX_1|MBX_0;
3515 mcp->in_mb = MBX_1|MBX_0;
3516 mcp->tov = MBX_TOV_SECONDS;
3517 mcp->flags = 0;
3518 rval = qla2x00_mailbox_command(vha, mcp);
3519
3520 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003521 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3522 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3523 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003524 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003525 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003526 }
3527
3528 return rval;
3529}
3530
3531int
3532qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3533{
3534 int rval;
3535 mbx_cmd_t mc;
3536 mbx_cmd_t *mcp = &mc;
3537
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003538 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003539 return QLA_FUNCTION_FAILED;
3540
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003541 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003542
3543 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3544 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3545 mcp->mb[2] = LSW(start);
3546 mcp->mb[3] = MSW(start);
3547 mcp->mb[4] = LSW(finish);
3548 mcp->mb[5] = MSW(finish);
3549 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3550 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3551 mcp->tov = MBX_TOV_SECONDS;
3552 mcp->flags = 0;
3553 rval = qla2x00_mailbox_command(vha, mcp);
3554
3555 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003556 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3557 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3558 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003559 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003560 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003561 }
3562
3563 return rval;
3564}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003565
3566int
3567qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3568{
3569 int rval = 0;
3570 mbx_cmd_t mc;
3571 mbx_cmd_t *mcp = &mc;
3572
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003573 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003574
3575 mcp->mb[0] = MBC_RESTART_MPI_FW;
3576 mcp->out_mb = MBX_0;
3577 mcp->in_mb = MBX_0|MBX_1;
3578 mcp->tov = MBX_TOV_SECONDS;
3579 mcp->flags = 0;
3580 rval = qla2x00_mailbox_command(vha, mcp);
3581
3582 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003583 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3584 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3585 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003586 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003587 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003588 }
3589
3590 return rval;
3591}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003592
3593int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003594qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3595 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003596{
3597 int rval;
3598 mbx_cmd_t mc;
3599 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003600 struct qla_hw_data *ha = vha->hw;
3601
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003602 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3603
Joe Carnuccio6766df92011-05-10 11:30:15 -07003604 if (!IS_FWI2_CAPABLE(ha))
3605 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003606
Joe Carnuccio6766df92011-05-10 11:30:15 -07003607 if (len == 1)
3608 opt |= BIT_0;
3609
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003610 mcp->mb[0] = MBC_READ_SFP;
3611 mcp->mb[1] = dev;
3612 mcp->mb[2] = MSW(sfp_dma);
3613 mcp->mb[3] = LSW(sfp_dma);
3614 mcp->mb[6] = MSW(MSD(sfp_dma));
3615 mcp->mb[7] = LSW(MSD(sfp_dma));
3616 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003617 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003618 mcp->mb[10] = opt;
3619 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio1bff6cc2011-05-10 11:30:11 -07003620 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003621 mcp->tov = MBX_TOV_SECONDS;
3622 mcp->flags = 0;
3623 rval = qla2x00_mailbox_command(vha, mcp);
3624
3625 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003626 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003627
3628 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003629 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3630 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003631 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003632 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003633 }
3634
3635 return rval;
3636}
3637
3638int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003639qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3640 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003641{
3642 int rval;
3643 mbx_cmd_t mc;
3644 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003645 struct qla_hw_data *ha = vha->hw;
3646
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003647 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3648
Joe Carnuccio6766df92011-05-10 11:30:15 -07003649 if (!IS_FWI2_CAPABLE(ha))
3650 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003651
Joe Carnuccio6766df92011-05-10 11:30:15 -07003652 if (len == 1)
3653 opt |= BIT_0;
3654
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003655 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003656 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003657
3658 mcp->mb[0] = MBC_WRITE_SFP;
3659 mcp->mb[1] = dev;
3660 mcp->mb[2] = MSW(sfp_dma);
3661 mcp->mb[3] = LSW(sfp_dma);
3662 mcp->mb[6] = MSW(MSD(sfp_dma));
3663 mcp->mb[7] = LSW(MSD(sfp_dma));
3664 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003665 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003666 mcp->mb[10] = opt;
3667 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003668 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003669 mcp->tov = MBX_TOV_SECONDS;
3670 mcp->flags = 0;
3671 rval = qla2x00_mailbox_command(vha, mcp);
3672
3673 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003674 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3675 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003676 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003677 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003678 }
3679
3680 return rval;
3681}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003682
3683int
3684qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3685 uint16_t size_in_bytes, uint16_t *actual_size)
3686{
3687 int rval;
3688 mbx_cmd_t mc;
3689 mbx_cmd_t *mcp = &mc;
3690
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003691 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3692
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003693 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003694 return QLA_FUNCTION_FAILED;
3695
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003696 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3697 mcp->mb[2] = MSW(stats_dma);
3698 mcp->mb[3] = LSW(stats_dma);
3699 mcp->mb[6] = MSW(MSD(stats_dma));
3700 mcp->mb[7] = LSW(MSD(stats_dma));
3701 mcp->mb[8] = size_in_bytes >> 2;
3702 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3703 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3704 mcp->tov = MBX_TOV_SECONDS;
3705 mcp->flags = 0;
3706 rval = qla2x00_mailbox_command(vha, mcp);
3707
3708 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003709 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3710 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3711 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003712 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003713 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3714
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003715
3716 *actual_size = mcp->mb[2] << 2;
3717 }
3718
3719 return rval;
3720}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003721
3722int
3723qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3724 uint16_t size)
3725{
3726 int rval;
3727 mbx_cmd_t mc;
3728 mbx_cmd_t *mcp = &mc;
3729
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003730 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3731
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003732 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003733 return QLA_FUNCTION_FAILED;
3734
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003735 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3736 mcp->mb[1] = 0;
3737 mcp->mb[2] = MSW(tlv_dma);
3738 mcp->mb[3] = LSW(tlv_dma);
3739 mcp->mb[6] = MSW(MSD(tlv_dma));
3740 mcp->mb[7] = LSW(MSD(tlv_dma));
3741 mcp->mb[8] = size;
3742 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3743 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3744 mcp->tov = MBX_TOV_SECONDS;
3745 mcp->flags = 0;
3746 rval = qla2x00_mailbox_command(vha, mcp);
3747
3748 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003749 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3750 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3751 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003752 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003753 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003754 }
3755
3756 return rval;
3757}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003758
3759int
3760qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3761{
3762 int rval;
3763 mbx_cmd_t mc;
3764 mbx_cmd_t *mcp = &mc;
3765
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003766 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3767
Andrew Vasquez18e75552009-06-03 09:55:30 -07003768 if (!IS_FWI2_CAPABLE(vha->hw))
3769 return QLA_FUNCTION_FAILED;
3770
Andrew Vasquez18e75552009-06-03 09:55:30 -07003771 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3772 mcp->mb[1] = LSW(risc_addr);
3773 mcp->mb[8] = MSW(risc_addr);
3774 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3775 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3776 mcp->tov = 30;
3777 mcp->flags = 0;
3778 rval = qla2x00_mailbox_command(vha, mcp);
3779 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003780 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3781 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003782 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003783 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003784 *data = mcp->mb[3] << 16 | mcp->mb[2];
3785 }
3786
3787 return rval;
3788}
3789
3790int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003791qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3792 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003793{
3794 int rval;
3795 mbx_cmd_t mc;
3796 mbx_cmd_t *mcp = &mc;
3797 uint32_t iter_cnt = 0x1;
3798
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003799 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003800
3801 memset(mcp->mb, 0 , sizeof(mcp->mb));
3802 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3803 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3804
3805 /* transfer count */
3806 mcp->mb[10] = LSW(mreq->transfer_size);
3807 mcp->mb[11] = MSW(mreq->transfer_size);
3808
3809 /* send data address */
3810 mcp->mb[14] = LSW(mreq->send_dma);
3811 mcp->mb[15] = MSW(mreq->send_dma);
3812 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3813 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3814
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003815 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003816 mcp->mb[16] = LSW(mreq->rcv_dma);
3817 mcp->mb[17] = MSW(mreq->rcv_dma);
3818 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3819 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3820
3821 /* Iteration count */
3822 mcp->mb[18] = LSW(iter_cnt);
3823 mcp->mb[19] = MSW(iter_cnt);
3824
3825 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3826 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003827 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003828 mcp->out_mb |= MBX_2;
3829 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3830
3831 mcp->buf_size = mreq->transfer_size;
3832 mcp->tov = MBX_TOV_SECONDS;
3833 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3834
3835 rval = qla2x00_mailbox_command(vha, mcp);
3836
3837 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003838 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3839 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3840 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3841 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003842 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003843 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003844 }
3845
3846 /* Copy mailbox information */
3847 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003848 return rval;
3849}
3850
3851int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003852qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3853 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003854{
3855 int rval;
3856 mbx_cmd_t mc;
3857 mbx_cmd_t *mcp = &mc;
3858 struct qla_hw_data *ha = vha->hw;
3859
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003860 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003861
3862 memset(mcp->mb, 0 , sizeof(mcp->mb));
3863 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3864 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003865 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003866 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003867 mcp->mb[2] = vha->fcoe_fcf_idx;
3868 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003869 mcp->mb[16] = LSW(mreq->rcv_dma);
3870 mcp->mb[17] = MSW(mreq->rcv_dma);
3871 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3872 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3873
3874 mcp->mb[10] = LSW(mreq->transfer_size);
3875
3876 mcp->mb[14] = LSW(mreq->send_dma);
3877 mcp->mb[15] = MSW(mreq->send_dma);
3878 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3879 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3880
3881 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3882 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003883 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003884 mcp->out_mb |= MBX_2;
3885
3886 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003887 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
3888 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003889 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003890 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003891 mcp->in_mb |= MBX_3;
3892
3893 mcp->tov = MBX_TOV_SECONDS;
3894 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3895 mcp->buf_size = mreq->transfer_size;
3896
3897 rval = qla2x00_mailbox_command(vha, mcp);
3898
3899 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003900 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3901 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3902 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003903 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003904 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003905 }
3906
3907 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003908 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003909 return rval;
3910}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003911
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003912int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003913qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003914{
3915 int rval;
3916 mbx_cmd_t mc;
3917 mbx_cmd_t *mcp = &mc;
3918
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003919 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3920 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003921
3922 mcp->mb[0] = MBC_ISP84XX_RESET;
3923 mcp->mb[1] = enable_diagnostic;
3924 mcp->out_mb = MBX_1|MBX_0;
3925 mcp->in_mb = MBX_1|MBX_0;
3926 mcp->tov = MBX_TOV_SECONDS;
3927 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003928 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003929
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003930 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003931 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003932 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003933 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003934
3935 return rval;
3936}
3937
3938int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003939qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3940{
3941 int rval;
3942 mbx_cmd_t mc;
3943 mbx_cmd_t *mcp = &mc;
3944
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003945 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3946
Andrew Vasquez18e75552009-06-03 09:55:30 -07003947 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003948 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003949
Andrew Vasquez18e75552009-06-03 09:55:30 -07003950 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3951 mcp->mb[1] = LSW(risc_addr);
3952 mcp->mb[2] = LSW(data);
3953 mcp->mb[3] = MSW(data);
3954 mcp->mb[8] = MSW(risc_addr);
3955 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3956 mcp->in_mb = MBX_0;
3957 mcp->tov = 30;
3958 mcp->flags = 0;
3959 rval = qla2x00_mailbox_command(vha, mcp);
3960 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003961 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3962 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003963 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003964 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003965 }
3966
3967 return rval;
3968}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003969
3970int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003971qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3972{
3973 int rval;
3974 uint32_t stat, timer;
3975 uint16_t mb0 = 0;
3976 struct qla_hw_data *ha = vha->hw;
3977 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3978
3979 rval = QLA_SUCCESS;
3980
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003981 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003982
3983 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3984
3985 /* Write the MBC data to the registers */
3986 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3987 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3988 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3989 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3990 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3991
3992 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3993
3994 /* Poll for MBC interrupt */
3995 for (timer = 6000000; timer; timer--) {
3996 /* Check for pending interrupts. */
3997 stat = RD_REG_DWORD(&reg->host_status);
3998 if (stat & HSRX_RISC_INT) {
3999 stat &= 0xff;
4000
4001 if (stat == 0x1 || stat == 0x2 ||
4002 stat == 0x10 || stat == 0x11) {
4003 set_bit(MBX_INTERRUPT,
4004 &ha->mbx_cmd_flags);
4005 mb0 = RD_REG_WORD(&reg->mailbox0);
4006 WRT_REG_DWORD(&reg->hccr,
4007 HCCRX_CLR_RISC_INT);
4008 RD_REG_DWORD(&reg->hccr);
4009 break;
4010 }
4011 }
4012 udelay(5);
4013 }
4014
4015 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4016 rval = mb0 & MBS_MASK;
4017 else
4018 rval = QLA_FUNCTION_FAILED;
4019
4020 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004021 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4022 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004023 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004024 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004025 }
4026
4027 return rval;
4028}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004029
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004030int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004031qla2x00_get_data_rate(scsi_qla_host_t *vha)
4032{
4033 int rval;
4034 mbx_cmd_t mc;
4035 mbx_cmd_t *mcp = &mc;
4036 struct qla_hw_data *ha = vha->hw;
4037
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004038 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
4039
Michael Hernandez3064ff32009-12-15 21:29:44 -08004040 if (!IS_FWI2_CAPABLE(ha))
4041 return QLA_FUNCTION_FAILED;
4042
Michael Hernandez3064ff32009-12-15 21:29:44 -08004043 mcp->mb[0] = MBC_DATA_RATE;
4044 mcp->mb[1] = 0;
4045 mcp->out_mb = MBX_1|MBX_0;
4046 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004047 if (IS_QLA83XX(ha))
4048 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004049 mcp->tov = MBX_TOV_SECONDS;
4050 mcp->flags = 0;
4051 rval = qla2x00_mailbox_command(vha, mcp);
4052 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004053 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4054 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004055 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004056 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004057 if (mcp->mb[1] != 0x7)
4058 ha->link_data_rate = mcp->mb[1];
4059 }
4060
4061 return rval;
4062}
Sarang Radke09ff7012010-03-19 17:03:59 -07004063
4064int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004065qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4066{
4067 int rval;
4068 mbx_cmd_t mc;
4069 mbx_cmd_t *mcp = &mc;
4070 struct qla_hw_data *ha = vha->hw;
4071
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004072 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004073
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004074 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004075 return QLA_FUNCTION_FAILED;
4076 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4077 mcp->out_mb = MBX_0;
4078 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4079 mcp->tov = MBX_TOV_SECONDS;
4080 mcp->flags = 0;
4081
4082 rval = qla2x00_mailbox_command(vha, mcp);
4083
4084 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004085 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4086 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004087 } else {
4088 /* Copy all bits to preserve original value */
4089 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4090
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004091 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004092 }
4093 return rval;
4094}
4095
4096int
4097qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4098{
4099 int rval;
4100 mbx_cmd_t mc;
4101 mbx_cmd_t *mcp = &mc;
4102
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004103 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004104
4105 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4106 /* Copy all bits to preserve original setting */
4107 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4108 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4109 mcp->in_mb = MBX_0;
4110 mcp->tov = MBX_TOV_SECONDS;
4111 mcp->flags = 0;
4112 rval = qla2x00_mailbox_command(vha, mcp);
4113
4114 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004115 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4116 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004117 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004118 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004119
4120 return rval;
4121}
4122
4123
4124int
Sarang Radke09ff7012010-03-19 17:03:59 -07004125qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4126 uint16_t *mb)
4127{
4128 int rval;
4129 mbx_cmd_t mc;
4130 mbx_cmd_t *mcp = &mc;
4131 struct qla_hw_data *ha = vha->hw;
4132
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004133 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4134
Sarang Radke09ff7012010-03-19 17:03:59 -07004135 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4136 return QLA_FUNCTION_FAILED;
4137
Sarang Radke09ff7012010-03-19 17:03:59 -07004138 mcp->mb[0] = MBC_PORT_PARAMS;
4139 mcp->mb[1] = loop_id;
4140 if (ha->flags.fcp_prio_enabled)
4141 mcp->mb[2] = BIT_1;
4142 else
4143 mcp->mb[2] = BIT_2;
4144 mcp->mb[4] = priority & 0xf;
4145 mcp->mb[9] = vha->vp_idx;
4146 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4147 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4148 mcp->tov = 30;
4149 mcp->flags = 0;
4150 rval = qla2x00_mailbox_command(vha, mcp);
4151 if (mb != NULL) {
4152 mb[0] = mcp->mb[0];
4153 mb[1] = mcp->mb[1];
4154 mb[3] = mcp->mb[3];
4155 mb[4] = mcp->mb[4];
4156 }
4157
4158 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004159 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004160 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004161 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004162 }
4163
4164 return rval;
4165}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004166
4167int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004168qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4169{
4170 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004171 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004172 struct qla_hw_data *ha = vha->hw;
4173
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004174 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004175
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004176 /* Integer part */
4177 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004178 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004179 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004180 ha->flags.thermal_supported = 0;
4181 goto fail;
4182 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004183 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004184
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004185 /* Fraction part */
4186 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004187 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004188 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004189 ha->flags.thermal_supported = 0;
4190 goto fail;
4191 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004192 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004193
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004194 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004195fail:
4196 return rval;
4197}
4198
4199int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004200qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4201{
4202 int rval;
4203 struct qla_hw_data *ha = vha->hw;
4204 mbx_cmd_t mc;
4205 mbx_cmd_t *mcp = &mc;
4206
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004207 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4208
Giridhar Malavalia9083012010-04-12 17:59:55 -07004209 if (!IS_FWI2_CAPABLE(ha))
4210 return QLA_FUNCTION_FAILED;
4211
Giridhar Malavalia9083012010-04-12 17:59:55 -07004212 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004213 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004214 mcp->mb[1] = 1;
4215
4216 mcp->out_mb = MBX_1|MBX_0;
4217 mcp->in_mb = MBX_0;
4218 mcp->tov = 30;
4219 mcp->flags = 0;
4220
4221 rval = qla2x00_mailbox_command(vha, mcp);
4222 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004223 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4224 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004225 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004226 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004227 }
4228
4229 return rval;
4230}
4231
4232int
4233qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4234{
4235 int rval;
4236 struct qla_hw_data *ha = vha->hw;
4237 mbx_cmd_t mc;
4238 mbx_cmd_t *mcp = &mc;
4239
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004240 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4241
Giridhar Malavalia9083012010-04-12 17:59:55 -07004242 if (!IS_QLA82XX(ha))
4243 return QLA_FUNCTION_FAILED;
4244
Giridhar Malavalia9083012010-04-12 17:59:55 -07004245 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004246 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004247 mcp->mb[1] = 0;
4248
4249 mcp->out_mb = MBX_1|MBX_0;
4250 mcp->in_mb = MBX_0;
4251 mcp->tov = 30;
4252 mcp->flags = 0;
4253
4254 rval = qla2x00_mailbox_command(vha, mcp);
4255 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004256 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4257 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004258 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004259 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004260 }
4261
4262 return rval;
4263}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004264
4265int
4266qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4267{
4268 struct qla_hw_data *ha = vha->hw;
4269 mbx_cmd_t mc;
4270 mbx_cmd_t *mcp = &mc;
4271 int rval = QLA_FUNCTION_FAILED;
4272
4273 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4274
4275 memset(mcp->mb, 0 , sizeof(mcp->mb));
4276 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4277 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4278 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4279 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4280
4281 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4282 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4283 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4284
4285 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4286 mcp->tov = MBX_TOV_SECONDS;
4287 rval = qla2x00_mailbox_command(vha, mcp);
4288
4289 /* Always copy back return mailbox values. */
4290 if (rval != QLA_SUCCESS) {
4291 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4292 "mailbox command FAILED=0x%x, subcode=%x.\n",
4293 (mcp->mb[1] << 16) | mcp->mb[0],
4294 (mcp->mb[3] << 16) | mcp->mb[2]);
4295 } else {
4296 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4297 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4298 if (!ha->md_template_size) {
4299 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4300 "Null template size obtained.\n");
4301 rval = QLA_FUNCTION_FAILED;
4302 }
4303 }
4304 return rval;
4305}
4306
4307int
4308qla82xx_md_get_template(scsi_qla_host_t *vha)
4309{
4310 struct qla_hw_data *ha = vha->hw;
4311 mbx_cmd_t mc;
4312 mbx_cmd_t *mcp = &mc;
4313 int rval = QLA_FUNCTION_FAILED;
4314
4315 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4316
4317 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4318 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4319 if (!ha->md_tmplt_hdr) {
4320 ql_log(ql_log_warn, vha, 0x1124,
4321 "Unable to allocate memory for Minidump template.\n");
4322 return rval;
4323 }
4324
4325 memset(mcp->mb, 0 , sizeof(mcp->mb));
4326 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4327 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4328 mcp->mb[2] = LSW(RQST_TMPLT);
4329 mcp->mb[3] = MSW(RQST_TMPLT);
4330 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4331 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4332 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4333 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4334 mcp->mb[8] = LSW(ha->md_template_size);
4335 mcp->mb[9] = MSW(ha->md_template_size);
4336
4337 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4338 mcp->tov = MBX_TOV_SECONDS;
4339 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4340 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4341 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4342 rval = qla2x00_mailbox_command(vha, mcp);
4343
4344 if (rval != QLA_SUCCESS) {
4345 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4346 "mailbox command FAILED=0x%x, subcode=%x.\n",
4347 ((mcp->mb[1] << 16) | mcp->mb[0]),
4348 ((mcp->mb[3] << 16) | mcp->mb[2]));
4349 } else
4350 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4351 return rval;
4352}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004353
4354int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004355qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4356{
4357 int rval;
4358 struct qla_hw_data *ha = vha->hw;
4359 mbx_cmd_t mc;
4360 mbx_cmd_t *mcp = &mc;
4361
4362 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4363 return QLA_FUNCTION_FAILED;
4364
4365 ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
4366
4367 memset(mcp, 0, sizeof(mbx_cmd_t));
4368 mcp->mb[0] = MBC_SET_LED_CONFIG;
4369 mcp->mb[1] = led_cfg[0];
4370 mcp->mb[2] = led_cfg[1];
4371 if (IS_QLA8031(ha)) {
4372 mcp->mb[3] = led_cfg[2];
4373 mcp->mb[4] = led_cfg[3];
4374 mcp->mb[5] = led_cfg[4];
4375 mcp->mb[6] = led_cfg[5];
4376 }
4377
4378 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4379 if (IS_QLA8031(ha))
4380 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4381 mcp->in_mb = MBX_0;
4382 mcp->tov = 30;
4383 mcp->flags = 0;
4384
4385 rval = qla2x00_mailbox_command(vha, mcp);
4386 if (rval != QLA_SUCCESS) {
4387 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4388 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4389 } else {
4390 ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
4391 }
4392
4393 return rval;
4394}
4395
4396int
4397qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4398{
4399 int rval;
4400 struct qla_hw_data *ha = vha->hw;
4401 mbx_cmd_t mc;
4402 mbx_cmd_t *mcp = &mc;
4403
4404 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4405 return QLA_FUNCTION_FAILED;
4406
4407 ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
4408
4409 memset(mcp, 0, sizeof(mbx_cmd_t));
4410 mcp->mb[0] = MBC_GET_LED_CONFIG;
4411
4412 mcp->out_mb = MBX_0;
4413 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4414 if (IS_QLA8031(ha))
4415 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4416 mcp->tov = 30;
4417 mcp->flags = 0;
4418
4419 rval = qla2x00_mailbox_command(vha, mcp);
4420 if (rval != QLA_SUCCESS) {
4421 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4422 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4423 } else {
4424 led_cfg[0] = mcp->mb[1];
4425 led_cfg[1] = mcp->mb[2];
4426 if (IS_QLA8031(ha)) {
4427 led_cfg[2] = mcp->mb[3];
4428 led_cfg[3] = mcp->mb[4];
4429 led_cfg[4] = mcp->mb[5];
4430 led_cfg[5] = mcp->mb[6];
4431 }
4432 ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
4433 }
4434
4435 return rval;
4436}
4437
4438int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004439qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4440{
4441 int rval;
4442 struct qla_hw_data *ha = vha->hw;
4443 mbx_cmd_t mc;
4444 mbx_cmd_t *mcp = &mc;
4445
4446 if (!IS_QLA82XX(ha))
4447 return QLA_FUNCTION_FAILED;
4448
4449 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4450 "Entered %s.\n", __func__);
4451
4452 memset(mcp, 0, sizeof(mbx_cmd_t));
4453 mcp->mb[0] = MBC_SET_LED_CONFIG;
4454 if (enable)
4455 mcp->mb[7] = 0xE;
4456 else
4457 mcp->mb[7] = 0xD;
4458
4459 mcp->out_mb = MBX_7|MBX_0;
4460 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004461 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004462 mcp->flags = 0;
4463
4464 rval = qla2x00_mailbox_command(vha, mcp);
4465 if (rval != QLA_SUCCESS) {
4466 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4467 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4468 } else {
4469 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4470 "Done %s.\n", __func__);
4471 }
4472
4473 return rval;
4474}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004475
4476int
4477qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4478{
4479 int rval;
4480 struct qla_hw_data *ha = vha->hw;
4481 mbx_cmd_t mc;
4482 mbx_cmd_t *mcp = &mc;
4483
4484 if (!IS_QLA83XX(ha))
4485 return QLA_FUNCTION_FAILED;
4486
4487 ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
4488
4489 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4490 mcp->mb[1] = LSW(reg);
4491 mcp->mb[2] = MSW(reg);
4492 mcp->mb[3] = LSW(data);
4493 mcp->mb[4] = MSW(data);
4494 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4495
4496 mcp->in_mb = MBX_1|MBX_0;
4497 mcp->tov = MBX_TOV_SECONDS;
4498 mcp->flags = 0;
4499 rval = qla2x00_mailbox_command(vha, mcp);
4500
4501 if (rval != QLA_SUCCESS) {
4502 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4503 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4504 } else {
4505 ql_dbg(ql_dbg_mbx, vha, 0x1132,
4506 "Done %s.\n", __func__);
4507 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004508
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004509 return rval;
4510}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004511
4512int
4513qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4514{
4515 int rval;
4516 struct qla_hw_data *ha = vha->hw;
4517 mbx_cmd_t mc;
4518 mbx_cmd_t *mcp = &mc;
4519
4520 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
4521 ql_dbg(ql_dbg_mbx, vha, 0x113b,
4522 "Implicit LOGO Unsupported.\n");
4523 return QLA_FUNCTION_FAILED;
4524 }
4525
4526
4527 ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__);
4528
4529 /* Perform Implicit LOGO. */
4530 mcp->mb[0] = MBC_PORT_LOGOUT;
4531 mcp->mb[1] = fcport->loop_id;
4532 mcp->mb[10] = BIT_15;
4533 mcp->out_mb = MBX_10|MBX_1|MBX_0;
4534 mcp->in_mb = MBX_0;
4535 mcp->tov = MBX_TOV_SECONDS;
4536 mcp->flags = 0;
4537 rval = qla2x00_mailbox_command(vha, mcp);
4538 if (rval != QLA_SUCCESS)
4539 ql_dbg(ql_dbg_mbx, vha, 0x113d,
4540 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4541 else
4542 ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__);
4543
4544 return rval;
4545}
4546