blob: f7604ea1af836b58e10d587be15d15283301e3da [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);
Giridhar Malavali862cd012011-02-23 15:27:11 -080082 rval = QLA_FUNCTION_FAILED;
83 goto premature_exit;
84 }
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070087 * Wait for active mailbox commands to finish by waiting at most tov
88 * seconds. This is to serialize actual issuing of mailbox cmds during
89 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080091 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
92 /* Timeout occurred. Return error. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -070093 ql_log(ql_log_warn, base_vha, 0x1005,
94 "Cmd access timeout, Exiting.\n");
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);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700166 ql_dbg(ql_dbg_mbx, base_vha, 0x1010,
167 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700168 rval = QLA_FUNCTION_TIMEOUT;
169 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700170 }
171 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
172 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700173 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
174 else
175 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 spin_unlock_irqrestore(&ha->hardware_lock, flags);
177
Marcus Barrow0b05a1f2008-01-17 09:02:13 -0800178 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
181
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700183 ql_dbg(ql_dbg_mbx, base_vha, 0x1011,
184 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Giridhar Malavalia9083012010-04-12 17:59:55 -0700186 if (IS_QLA82XX(ha)) {
187 if (RD_REG_DWORD(&reg->isp82.hint) &
188 HINT_MBX_INT_PENDING) {
189 spin_unlock_irqrestore(&ha->hardware_lock,
190 flags);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700191 ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
192 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700193 rval = QLA_FUNCTION_TIMEOUT;
194 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700195 }
196 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
197 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700198 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
199 else
200 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202
203 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
204 while (!ha->flags.mbox_int) {
205 if (time_after(jiffies, wait_time))
206 break;
207
208 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800209 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
Andrew Vasquez85880802009-12-15 21:29:46 -0800211 if (!ha->flags.mbox_int &&
212 !(IS_QLA2200(ha) &&
213 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800214 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 } /* while */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700216 ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
217 "Waited %d sec.\n",
218 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 }
220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 /* Check whether we timed out */
222 if (ha->flags.mbox_int) {
223 uint16_t *iptr2;
224
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700225 ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
226 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227
228 /* Got interrupt. Clear the flag. */
229 ha->flags.mbox_int = 0;
230 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
231
Giridhar Malavali71905752011-02-23 15:27:10 -0800232 if (ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700233 ha->flags.mbox_busy = 0;
234 /* Setting Link-Down error */
235 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
236 ha->mcp = NULL;
237 rval = QLA_FUNCTION_FAILED;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700238 ql_log(ql_log_warn, base_vha, 0x1015,
239 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700240 goto premature_exit;
241 }
242
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400243 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
246 /* Load return mailbox registers. */
247 iptr2 = mcp->mb;
248 iptr = (uint16_t *)&ha->mailbox_out[0];
249 mboxes = mcp->in_mb;
250 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
251 if (mboxes & BIT_0)
252 *iptr2 = *iptr;
253
254 mboxes >>= 1;
255 iptr2++;
256 iptr++;
257 }
258 } else {
259
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700260 uint16_t mb0;
261 uint32_t ictrl;
262
Andrew Vasqueze4289242007-07-19 15:05:56 -0700263 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700264 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
265 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
266 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700267 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700268 ictrl = RD_REG_WORD(&reg->isp.ictrl);
269 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700270 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
271 "MBX Command timeout for cmd %x.\n", command);
272 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
273 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
274 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
275 "mb[0] = 0x%x.\n", mb0);
276 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 rval = QLA_FUNCTION_TIMEOUT;
279 }
280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 ha->flags.mbox_busy = 0;
282
283 /* Clean up */
284 ha->mcp = NULL;
285
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800286 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700287 ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
288 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
290 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800291 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 }
293
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700294 if (rval == QLA_FUNCTION_TIMEOUT &&
295 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800296 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
297 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 /* not in dpc. schedule it for dpc to take over. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700299 ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
300 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700301
302 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
303 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
304 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
305
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700306 ql_log(ql_log_info, base_vha, 0x101c,
307 "Mailbox cmd timeout occured. "
308 "Scheduling ISP abort eeh_busy=0x%x.\n",
309 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700310 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
311 qla2xxx_wake_dpc(vha);
312 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 /* call abort directly since we are in the DPC thread */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700315 ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
316 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700318 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
319 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
320 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
321
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700322 ql_log(ql_log_info, base_vha, 0x101e,
323 "Mailbox cmd timeout occured. "
324 "Scheduling ISP abort.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700325
326 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
327 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
328 if (ha->isp_ops->abort_isp(vha)) {
329 /* Failed. retry later. */
330 set_bit(ISP_ABORT_NEEDED,
331 &vha->dpc_flags);
332 }
333 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700334 ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
335 "Finished abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 }
338 }
339
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700340premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800342 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343
344 if (rval) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700345 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
346 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, cmd=%x ****.\n",
347 mcp->mb[0], mcp->mb[1], mcp->mb[2], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700349 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 }
351
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return rval;
353}
354
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800356qla2x00_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 -0800357 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358{
359 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800360 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 mbx_cmd_t mc;
362 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700364 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Andrew Vasqueze4289242007-07-19 15:05:56 -0700366 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800367 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
368 mcp->mb[8] = MSW(risc_addr);
369 mcp->out_mb = MBX_8|MBX_0;
370 } else {
371 mcp->mb[0] = MBC_LOAD_RISC_RAM;
372 mcp->out_mb = MBX_0;
373 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 mcp->mb[1] = LSW(risc_addr);
375 mcp->mb[2] = MSW(req_dma);
376 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 mcp->mb[6] = MSW(MSD(req_dma));
378 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800379 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700380 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700381 mcp->mb[4] = MSW(risc_code_size);
382 mcp->mb[5] = LSW(risc_code_size);
383 mcp->out_mb |= MBX_5|MBX_4;
384 } else {
385 mcp->mb[4] = LSW(risc_code_size);
386 mcp->out_mb |= MBX_4;
387 }
388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700390 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800392 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700395 ql_dbg(ql_dbg_mbx, vha, 0x1023,
396 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700398 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 }
400
401 return rval;
402}
403
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700404#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405/*
406 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700407 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 *
409 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700410 * ha = adapter block pointer.
411 * TARGET_QUEUE_LOCK must be released.
412 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 *
414 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700415 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 *
417 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700418 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 */
420int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800421qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422{
423 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800424 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 mbx_cmd_t mc;
426 mbx_cmd_t *mcp = &mc;
427
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700428 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700431 mcp->out_mb = MBX_0;
432 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700433 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700434 mcp->mb[1] = MSW(risc_addr);
435 mcp->mb[2] = LSW(risc_addr);
436 mcp->mb[3] = 0;
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700437 if (IS_QLA81XX(ha)) {
438 struct nvram_81xx *nv = ha->nvram;
439 mcp->mb[4] = (nv->enhanced_features &
440 EXTENDED_BB_CREDITS);
441 } else
442 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700443 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700444 mcp->in_mb |= MBX_1;
445 } else {
446 mcp->mb[1] = LSW(risc_addr);
447 mcp->out_mb |= MBX_1;
448 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
449 mcp->mb[2] = 0;
450 mcp->out_mb |= MBX_2;
451 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 }
453
Ravi Anandb93480e2008-04-03 13:13:25 -0700454 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800456 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700458 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700459 ql_dbg(ql_dbg_mbx, vha, 0x1026,
460 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700461 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700462 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700463 ql_dbg(ql_dbg_mbx, vha, 0x1027,
464 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700466 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700467 }
468 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469
470 return rval;
471}
472
473/*
474 * qla2x00_get_fw_version
475 * Get firmware version.
476 *
477 * Input:
478 * ha: adapter state pointer.
479 * major: pointer for major number.
480 * minor: pointer for minor number.
481 * subminor: pointer for subminor number.
482 *
483 * Returns:
484 * qla2x00 local function return status code.
485 *
486 * Context:
487 * Kernel context.
488 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700489int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800490qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800491 uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
Andrew Vasquez55a96152009-03-24 09:08:03 -0700492 uint32_t *mpi_caps, uint8_t *phy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
494 int rval;
495 mbx_cmd_t mc;
496 mbx_cmd_t *mcp = &mc;
497
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700498 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
501 mcp->out_mb = MBX_0;
502 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800503 if (IS_QLA81XX(vha->hw))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700504 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700506 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800507 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700508 if (rval != QLA_SUCCESS)
509 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
511 /* Return mailbox data. */
512 *major = mcp->mb[1];
513 *minor = mcp->mb[2];
514 *subminor = mcp->mb[3];
515 *attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800516 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 *memory = 0x1FFFF; /* Defaults to 128KB. */
518 else
519 *memory = (mcp->mb[5] << 16) | mcp->mb[4];
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800520 if (IS_QLA81XX(vha->hw)) {
Andrew Vasquez55a96152009-03-24 09:08:03 -0700521 mpi[0] = mcp->mb[10] & 0xff;
522 mpi[1] = mcp->mb[11] >> 8;
523 mpi[2] = mcp->mb[11] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800524 *mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
Andrew Vasquez55a96152009-03-24 09:08:03 -0700525 phy[0] = mcp->mb[8] & 0xff;
526 phy[1] = mcp->mb[9] >> 8;
527 phy[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800528 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700529failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if (rval != QLA_SUCCESS) {
531 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700532 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 } else {
534 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700535 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700537 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538}
539
540/*
541 * qla2x00_get_fw_options
542 * Set firmware options.
543 *
544 * Input:
545 * ha = adapter block pointer.
546 * fwopt = pointer for firmware options.
547 *
548 * Returns:
549 * qla2x00 local function return status code.
550 *
551 * Context:
552 * Kernel context.
553 */
554int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800555qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556{
557 int rval;
558 mbx_cmd_t mc;
559 mbx_cmd_t *mcp = &mc;
560
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700561 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
563 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
564 mcp->out_mb = MBX_0;
565 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700566 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800568 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
570 if (rval != QLA_SUCCESS) {
571 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700572 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700574 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 fwopts[1] = mcp->mb[1];
576 fwopts[2] = mcp->mb[2];
577 fwopts[3] = mcp->mb[3];
578
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700579 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 }
581
582 return rval;
583}
584
585
586/*
587 * qla2x00_set_fw_options
588 * Set firmware options.
589 *
590 * Input:
591 * ha = adapter block pointer.
592 * fwopt = pointer for firmware options.
593 *
594 * Returns:
595 * qla2x00 local function return status code.
596 *
597 * Context:
598 * Kernel context.
599 */
600int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800601qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602{
603 int rval;
604 mbx_cmd_t mc;
605 mbx_cmd_t *mcp = &mc;
606
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700607 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
609 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
610 mcp->mb[1] = fwopts[1];
611 mcp->mb[2] = fwopts[2];
612 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700613 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800615 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700616 mcp->in_mb |= MBX_1;
617 } else {
618 mcp->mb[10] = fwopts[10];
619 mcp->mb[11] = fwopts[11];
620 mcp->mb[12] = 0; /* Undocumented, but used */
621 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
622 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700623 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800625 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700627 fwopts[0] = mcp->mb[0];
628
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 if (rval != QLA_SUCCESS) {
630 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700631 ql_dbg(ql_dbg_mbx, vha, 0x1030,
632 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 } else {
634 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700635 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 }
637
638 return rval;
639}
640
641/*
642 * qla2x00_mbx_reg_test
643 * Mailbox register wrap test.
644 *
645 * Input:
646 * ha = adapter block pointer.
647 * TARGET_QUEUE_LOCK must be released.
648 * ADAPTER_STATE_LOCK must be released.
649 *
650 * Returns:
651 * qla2x00 local function return status code.
652 *
653 * Context:
654 * Kernel context.
655 */
656int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800657qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658{
659 int rval;
660 mbx_cmd_t mc;
661 mbx_cmd_t *mcp = &mc;
662
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700663 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
665 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
666 mcp->mb[1] = 0xAAAA;
667 mcp->mb[2] = 0x5555;
668 mcp->mb[3] = 0xAA55;
669 mcp->mb[4] = 0x55AA;
670 mcp->mb[5] = 0xA5A5;
671 mcp->mb[6] = 0x5A5A;
672 mcp->mb[7] = 0x2525;
673 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
674 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 -0700675 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800677 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
679 if (rval == QLA_SUCCESS) {
680 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
681 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
682 rval = QLA_FUNCTION_FAILED;
683 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
684 mcp->mb[7] != 0x2525)
685 rval = QLA_FUNCTION_FAILED;
686 }
687
688 if (rval != QLA_SUCCESS) {
689 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700690 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 } else {
692 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700693 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 }
695
696 return rval;
697}
698
699/*
700 * qla2x00_verify_checksum
701 * Verify firmware checksum.
702 *
703 * Input:
704 * ha = adapter block pointer.
705 * TARGET_QUEUE_LOCK must be released.
706 * ADAPTER_STATE_LOCK must be released.
707 *
708 * Returns:
709 * qla2x00 local function return status code.
710 *
711 * Context:
712 * Kernel context.
713 */
714int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800715qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716{
717 int rval;
718 mbx_cmd_t mc;
719 mbx_cmd_t *mcp = &mc;
720
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700721 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700724 mcp->out_mb = MBX_0;
725 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800726 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700727 mcp->mb[1] = MSW(risc_addr);
728 mcp->mb[2] = LSW(risc_addr);
729 mcp->out_mb |= MBX_2|MBX_1;
730 mcp->in_mb |= MBX_2|MBX_1;
731 } else {
732 mcp->mb[1] = LSW(risc_addr);
733 mcp->out_mb |= MBX_1;
734 mcp->in_mb |= MBX_1;
735 }
736
Ravi Anandb93480e2008-04-03 13:13:25 -0700737 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800739 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700742 ql_dbg(ql_dbg_mbx, vha, 0x1036,
743 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
744 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700746 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 }
748
749 return rval;
750}
751
752/*
753 * qla2x00_issue_iocb
754 * Issue IOCB using mailbox command
755 *
756 * Input:
757 * ha = adapter state pointer.
758 * buffer = buffer pointer.
759 * phys_addr = physical address of buffer.
760 * size = size of buffer.
761 * TARGET_QUEUE_LOCK must be released.
762 * ADAPTER_STATE_LOCK must be released.
763 *
764 * Returns:
765 * qla2x00 local function return status code.
766 *
767 * Context:
768 * Kernel context.
769 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700770int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800771qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700772 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773{
774 int rval;
775 mbx_cmd_t mc;
776 mbx_cmd_t *mcp = &mc;
777
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700778 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
781 mcp->mb[1] = 0;
782 mcp->mb[2] = MSW(phys_addr);
783 mcp->mb[3] = LSW(phys_addr);
784 mcp->mb[6] = MSW(MSD(phys_addr));
785 mcp->mb[7] = LSW(MSD(phys_addr));
786 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
787 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700788 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800790 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791
792 if (rval != QLA_SUCCESS) {
793 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700794 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700796 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
797
798 /* Mask reserved bits. */
799 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800800 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700801 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 }
803
804 return rval;
805}
806
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700807int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800808qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700809 size_t size)
810{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800811 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700812 MBX_TOV_SECONDS);
813}
814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815/*
816 * qla2x00_abort_command
817 * Abort command aborts a specified IOCB.
818 *
819 * Input:
820 * ha = adapter block pointer.
821 * sp = SB structure pointer.
822 *
823 * Returns:
824 * qla2x00 local function return status code.
825 *
826 * Context:
827 * Kernel context.
828 */
829int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700830qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831{
832 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800834 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 mbx_cmd_t mc;
836 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700837 fc_port_t *fcport = sp->fcport;
838 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800839 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700840 struct req_que *req = vha->req;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700842 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700844 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800846 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 break;
848 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700849 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851 if (handle == MAX_OUTSTANDING_COMMANDS) {
852 /* command not found */
853 return QLA_FUNCTION_FAILED;
854 }
855
856 mcp->mb[0] = MBC_ABORT_COMMAND;
857 if (HAS_EXTENDED_IDS(ha))
858 mcp->mb[1] = fcport->loop_id;
859 else
860 mcp->mb[1] = fcport->loop_id << 8;
861 mcp->mb[2] = (uint16_t)handle;
862 mcp->mb[3] = (uint16_t)(handle >> 16);
bdf79622005-04-17 15:06:53 -0500863 mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
865 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700866 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800868 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869
870 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700871 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700873 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 }
875
876 return rval;
877}
878
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700880qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700882 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 mbx_cmd_t mc;
884 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800885 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800886 struct req_que *req;
887 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Andrew Vasquez523ec772008-04-03 13:13:24 -0700889 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800890 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700891
892 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
893
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700894 req = vha->hw->req_q_map[0];
895 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700897 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800898 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899 mcp->mb[1] = fcport->loop_id;
900 mcp->mb[10] = 0;
901 mcp->out_mb |= MBX_10;
902 } else {
903 mcp->mb[1] = fcport->loop_id << 8;
904 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800905 mcp->mb[2] = vha->hw->loop_reset_delay;
906 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907
908 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700909 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800911 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700913 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700914 }
915
916 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800917 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
918 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700919 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700920 ql_dbg(ql_dbg_mbx, vha, 0x1040,
921 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700923 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700924 }
925
926 return rval;
927}
928
929int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700930qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700931{
932 int rval, rval2;
933 mbx_cmd_t mc;
934 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800935 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800936 struct req_que *req;
937 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700938
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800939 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700940
941 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
942
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700943 req = vha->hw->req_q_map[0];
944 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700945 mcp->mb[0] = MBC_LUN_RESET;
946 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800947 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700948 mcp->mb[1] = fcport->loop_id;
949 else
950 mcp->mb[1] = fcport->loop_id << 8;
951 mcp->mb[2] = l;
952 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800953 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700954
955 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700956 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700957 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800958 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700959 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700960 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700961 }
962
963 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800964 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
965 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700966 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700967 ql_dbg(ql_dbg_mbx, vha, 0x1044,
968 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700969 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700970 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 }
972
973 return rval;
974}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
976/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 * qla2x00_get_adapter_id
978 * Get adapter ID and topology.
979 *
980 * Input:
981 * ha = adapter block pointer.
982 * id = pointer for loop ID.
983 * al_pa = pointer for AL_PA.
984 * area = pointer for area.
985 * domain = pointer for domain.
986 * top = pointer for topology.
987 * TARGET_QUEUE_LOCK must be released.
988 * ADAPTER_STATE_LOCK must be released.
989 *
990 * Returns:
991 * qla2x00 local function return status code.
992 *
993 * Context:
994 * Kernel context.
995 */
996int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800997qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700998 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999{
1000 int rval;
1001 mbx_cmd_t mc;
1002 mbx_cmd_t *mcp = &mc;
1003
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001004 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001007 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001008 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001009 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavalia9083012010-04-12 17:59:55 -07001010 if (IS_QLA8XXX_TYPE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001011 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001012 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001014 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001015 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1016 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001017 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1018 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020 /* Return data. */
1021 *id = mcp->mb[1];
1022 *al_pa = LSB(mcp->mb[2]);
1023 *area = MSB(mcp->mb[2]);
1024 *domain = LSB(mcp->mb[3]);
1025 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001026 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
1028 if (rval != QLA_SUCCESS) {
1029 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001030 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001032 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001033
Giridhar Malavalia9083012010-04-12 17:59:55 -07001034 if (IS_QLA8XXX_TYPE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001035 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1036 vha->fcoe_fcf_idx = mcp->mb[10];
1037 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1038 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1039 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1040 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1041 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1042 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1043 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 }
1045
1046 return rval;
1047}
1048
1049/*
1050 * qla2x00_get_retry_cnt
1051 * Get current firmware login retry count and delay.
1052 *
1053 * Input:
1054 * ha = adapter block pointer.
1055 * retry_cnt = pointer to login retry count.
1056 * tov = pointer to login timeout value.
1057 *
1058 * Returns:
1059 * qla2x00 local function return status code.
1060 *
1061 * Context:
1062 * Kernel context.
1063 */
1064int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001065qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 uint16_t *r_a_tov)
1067{
1068 int rval;
1069 uint16_t ratov;
1070 mbx_cmd_t mc;
1071 mbx_cmd_t *mcp = &mc;
1072
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001073 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
1075 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1076 mcp->out_mb = MBX_0;
1077 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001078 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001080 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
1082 if (rval != QLA_SUCCESS) {
1083 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001084 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1085 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 } else {
1087 /* Convert returned data and check our values. */
1088 *r_a_tov = mcp->mb[3] / 2;
1089 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1090 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1091 /* Update to the larger values */
1092 *retry_cnt = (uint8_t)mcp->mb[1];
1093 *tov = ratov;
1094 }
1095
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001096 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1097 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 }
1099
1100 return rval;
1101}
1102
1103/*
1104 * qla2x00_init_firmware
1105 * Initialize adapter firmware.
1106 *
1107 * Input:
1108 * ha = adapter block pointer.
1109 * dptr = Initialization control block pointer.
1110 * size = size of initialization control block.
1111 * TARGET_QUEUE_LOCK must be released.
1112 * ADAPTER_STATE_LOCK must be released.
1113 *
1114 * Returns:
1115 * qla2x00 local function return status code.
1116 *
1117 * Context:
1118 * Kernel context.
1119 */
1120int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001121qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122{
1123 int rval;
1124 mbx_cmd_t mc;
1125 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001126 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001128 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129
Giridhar Malavalia9083012010-04-12 17:59:55 -07001130 if (IS_QLA82XX(ha) && ql2xdbwr)
1131 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1132 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1133
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001134 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001135 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1136 else
1137 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1138
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001139 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 mcp->mb[2] = MSW(ha->init_cb_dma);
1141 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1143 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001144 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1145 if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
1146 mcp->mb[1] = BIT_0;
1147 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1148 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1149 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1150 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1151 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1152 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1153 }
1154 mcp->in_mb = MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 mcp->buf_size = size;
1156 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001157 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001158 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
1160 if (rval != QLA_SUCCESS) {
1161 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001162 ql_dbg(ql_dbg_mbx, vha, 0x104d,
1163 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 } else {
1165 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001166 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 }
1168
1169 return rval;
1170}
1171
1172/*
1173 * qla2x00_get_port_database
1174 * Issue normal/enhanced get port database mailbox command
1175 * and copy device name as necessary.
1176 *
1177 * Input:
1178 * ha = adapter state pointer.
1179 * dev = structure pointer.
1180 * opt = enhanced cmd option byte.
1181 *
1182 * Returns:
1183 * qla2x00 local function return status code.
1184 *
1185 * Context:
1186 * Kernel context.
1187 */
1188int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001189qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190{
1191 int rval;
1192 mbx_cmd_t mc;
1193 mbx_cmd_t *mcp = &mc;
1194 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001195 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001197 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001199 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001201 pd24 = NULL;
1202 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001204 ql_log(ql_log_warn, vha, 0x1050,
1205 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 return QLA_MEMORY_ALLOC_FAILED;
1207 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001208 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001210 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001211 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 mcp->mb[2] = MSW(pd_dma);
1214 mcp->mb[3] = LSW(pd_dma);
1215 mcp->mb[6] = MSW(MSD(pd_dma));
1216 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001217 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001218 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001220 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001221 mcp->mb[1] = fcport->loop_id;
1222 mcp->mb[10] = opt;
1223 mcp->out_mb |= MBX_10|MBX_1;
1224 mcp->in_mb |= MBX_1;
1225 } else if (HAS_EXTENDED_IDS(ha)) {
1226 mcp->mb[1] = fcport->loop_id;
1227 mcp->mb[10] = opt;
1228 mcp->out_mb |= MBX_10|MBX_1;
1229 } else {
1230 mcp->mb[1] = fcport->loop_id << 8 | opt;
1231 mcp->out_mb |= MBX_1;
1232 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001233 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1234 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 mcp->flags = MBX_DMA_IN;
1236 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001237 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 if (rval != QLA_SUCCESS)
1239 goto gpd_error_out;
1240
Andrew Vasqueze4289242007-07-19 15:05:56 -07001241 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001242 pd24 = (struct port_database_24xx *) pd;
1243
1244 /* Check for logged in state. */
1245 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1246 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001247 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1248 "Unable to verify login-state (%x/%x) for "
1249 "loop_id %x.\n", pd24->current_login_state,
1250 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001251 rval = QLA_FUNCTION_FAILED;
1252 goto gpd_error_out;
1253 }
1254
1255 /* Names are little-endian. */
1256 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1257 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1258
1259 /* Get port_id of device. */
1260 fcport->d_id.b.domain = pd24->port_id[0];
1261 fcport->d_id.b.area = pd24->port_id[1];
1262 fcport->d_id.b.al_pa = pd24->port_id[2];
1263 fcport->d_id.b.rsvd_1 = 0;
1264
1265 /* If not target must be initiator or unknown type. */
1266 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1267 fcport->port_type = FCT_INITIATOR;
1268 else
1269 fcport->port_type = FCT_TARGET;
1270 } else {
1271 /* Check for logged in state. */
1272 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1273 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001274 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1275 "Unable to verify login-state (%x/%x) - "
1276 "portid=%02x%02x%02x.\n", pd->master_state,
1277 pd->slave_state, fcport->d_id.b.domain,
1278 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001279 rval = QLA_FUNCTION_FAILED;
1280 goto gpd_error_out;
1281 }
1282
1283 /* Names are little-endian. */
1284 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1285 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1286
1287 /* Get port_id of device. */
1288 fcport->d_id.b.domain = pd->port_id[0];
1289 fcport->d_id.b.area = pd->port_id[3];
1290 fcport->d_id.b.al_pa = pd->port_id[2];
1291 fcport->d_id.b.rsvd_1 = 0;
1292
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001293 /* If not target must be initiator or unknown type. */
1294 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1295 fcport->port_type = FCT_INITIATOR;
1296 else
1297 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001298
1299 /* Passback COS information. */
1300 fcport->supported_classes = (pd->options & BIT_4) ?
1301 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 }
1303
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304gpd_error_out:
1305 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1306
1307 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001308 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1309 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1310 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001312 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 }
1314
1315 return rval;
1316}
1317
1318/*
1319 * qla2x00_get_firmware_state
1320 * Get adapter firmware state.
1321 *
1322 * Input:
1323 * ha = adapter block pointer.
1324 * dptr = pointer for firmware state.
1325 * TARGET_QUEUE_LOCK must be released.
1326 * ADAPTER_STATE_LOCK must be released.
1327 *
1328 * Returns:
1329 * qla2x00 local function return status code.
1330 *
1331 * Context:
1332 * Kernel context.
1333 */
1334int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001335qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336{
1337 int rval;
1338 mbx_cmd_t mc;
1339 mbx_cmd_t *mcp = &mc;
1340
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001341 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
1343 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1344 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001345 if (IS_FWI2_CAPABLE(vha->hw))
1346 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1347 else
1348 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001349 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001351 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001353 /* Return firmware states. */
1354 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001355 if (IS_FWI2_CAPABLE(vha->hw)) {
1356 states[1] = mcp->mb[2];
1357 states[2] = mcp->mb[3];
1358 states[3] = mcp->mb[4];
1359 states[4] = mcp->mb[5];
1360 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
1362 if (rval != QLA_SUCCESS) {
1363 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001364 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 } else {
1366 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001367 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 }
1369
1370 return rval;
1371}
1372
1373/*
1374 * qla2x00_get_port_name
1375 * Issue get port name mailbox command.
1376 * Returned name is in big endian format.
1377 *
1378 * Input:
1379 * ha = adapter block pointer.
1380 * loop_id = loop ID of device.
1381 * name = pointer for name.
1382 * TARGET_QUEUE_LOCK must be released.
1383 * ADAPTER_STATE_LOCK must be released.
1384 *
1385 * Returns:
1386 * qla2x00 local function return status code.
1387 *
1388 * Context:
1389 * Kernel context.
1390 */
1391int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001392qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 uint8_t opt)
1394{
1395 int rval;
1396 mbx_cmd_t mc;
1397 mbx_cmd_t *mcp = &mc;
1398
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001399 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
1401 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001402 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001403 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001404 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 mcp->mb[1] = loop_id;
1406 mcp->mb[10] = opt;
1407 mcp->out_mb |= MBX_10;
1408 } else {
1409 mcp->mb[1] = loop_id << 8 | opt;
1410 }
1411
1412 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001413 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001415 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 if (rval != QLA_SUCCESS) {
1418 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001419 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 } else {
1421 if (name != NULL) {
1422 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001423 name[0] = MSB(mcp->mb[2]);
1424 name[1] = LSB(mcp->mb[2]);
1425 name[2] = MSB(mcp->mb[3]);
1426 name[3] = LSB(mcp->mb[3]);
1427 name[4] = MSB(mcp->mb[6]);
1428 name[5] = LSB(mcp->mb[6]);
1429 name[6] = MSB(mcp->mb[7]);
1430 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
1432
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001433 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
1435
1436 return rval;
1437}
1438
1439/*
1440 * qla2x00_lip_reset
1441 * Issue LIP reset mailbox command.
1442 *
1443 * Input:
1444 * ha = adapter block pointer.
1445 * TARGET_QUEUE_LOCK must be released.
1446 * ADAPTER_STATE_LOCK must be released.
1447 *
1448 * Returns:
1449 * qla2x00 local function return status code.
1450 *
1451 * Context:
1452 * Kernel context.
1453 */
1454int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001455qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456{
1457 int rval;
1458 mbx_cmd_t mc;
1459 mbx_cmd_t *mcp = &mc;
1460
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001461 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
Giridhar Malavalia9083012010-04-12 17:59:55 -07001463 if (IS_QLA8XXX_TYPE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001464 /* Logout across all FCFs. */
1465 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1466 mcp->mb[1] = BIT_1;
1467 mcp->mb[2] = 0;
1468 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1469 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001470 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001471 mcp->mb[1] = BIT_6;
1472 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001473 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001474 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001476 mcp->mb[0] = MBC_LIP_RESET;
1477 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001478 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001479 mcp->mb[1] = 0x00ff;
1480 mcp->mb[10] = 0;
1481 mcp->out_mb |= MBX_10;
1482 } else {
1483 mcp->mb[1] = 0xff00;
1484 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001485 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001486 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001489 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001491 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
1493 if (rval != QLA_SUCCESS) {
1494 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001495 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 } else {
1497 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001498 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 }
1500
1501 return rval;
1502}
1503
1504/*
1505 * qla2x00_send_sns
1506 * Send SNS command.
1507 *
1508 * Input:
1509 * ha = adapter block pointer.
1510 * sns = pointer for command.
1511 * cmd_size = command size.
1512 * buf_size = response/command size.
1513 * TARGET_QUEUE_LOCK must be released.
1514 * ADAPTER_STATE_LOCK must be released.
1515 *
1516 * Returns:
1517 * qla2x00 local function return status code.
1518 *
1519 * Context:
1520 * Kernel context.
1521 */
1522int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001523qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 uint16_t cmd_size, size_t buf_size)
1525{
1526 int rval;
1527 mbx_cmd_t mc;
1528 mbx_cmd_t *mcp = &mc;
1529
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001530 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001532 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1533 "Retry cnt=%d ratov=%d total tov=%d.\n",
1534 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535
1536 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1537 mcp->mb[1] = cmd_size;
1538 mcp->mb[2] = MSW(sns_phys_address);
1539 mcp->mb[3] = LSW(sns_phys_address);
1540 mcp->mb[6] = MSW(MSD(sns_phys_address));
1541 mcp->mb[7] = LSW(MSD(sns_phys_address));
1542 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1543 mcp->in_mb = MBX_0|MBX_1;
1544 mcp->buf_size = buf_size;
1545 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001546 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1547 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
1549 if (rval != QLA_SUCCESS) {
1550 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001551 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1552 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1553 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 } else {
1555 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001556 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 }
1558
1559 return rval;
1560}
1561
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001562int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001563qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001564 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1565{
1566 int rval;
1567
1568 struct logio_entry_24xx *lg;
1569 dma_addr_t lg_dma;
1570 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001571 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001572 struct req_que *req;
1573 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001574
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001575 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001576
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001577 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001578 req = ha->req_q_map[0];
1579 else
1580 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001581 rsp = req->rsp;
1582
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001583 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1584 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001585 ql_log(ql_log_warn, vha, 0x1062,
1586 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001587 return QLA_MEMORY_ALLOC_FAILED;
1588 }
1589 memset(lg, 0, sizeof(struct logio_entry_24xx));
1590
1591 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1592 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001593 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001594 lg->nport_handle = cpu_to_le16(loop_id);
1595 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1596 if (opt & BIT_0)
1597 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001598 if (opt & BIT_1)
1599 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001600 lg->port_id[0] = al_pa;
1601 lg->port_id[1] = area;
1602 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001603 lg->vp_index = vha->vp_idx;
1604 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001605 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001606 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1607 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001608 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001609 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1610 "Failed to complete IOCB -- error status (%x).\n",
1611 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001612 rval = QLA_FUNCTION_FAILED;
1613 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1614 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1615 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1616
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001617 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1618 "Failed to complete IOCB -- completion status (%x) "
1619 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1620 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001621
1622 switch (iop[0]) {
1623 case LSC_SCODE_PORTID_USED:
1624 mb[0] = MBS_PORT_ID_USED;
1625 mb[1] = LSW(iop[1]);
1626 break;
1627 case LSC_SCODE_NPORT_USED:
1628 mb[0] = MBS_LOOP_ID_USED;
1629 break;
1630 case LSC_SCODE_NOLINK:
1631 case LSC_SCODE_NOIOCB:
1632 case LSC_SCODE_NOXCB:
1633 case LSC_SCODE_CMD_FAILED:
1634 case LSC_SCODE_NOFABRIC:
1635 case LSC_SCODE_FW_NOT_READY:
1636 case LSC_SCODE_NOT_LOGGED_IN:
1637 case LSC_SCODE_NOPCB:
1638 case LSC_SCODE_ELS_REJECT:
1639 case LSC_SCODE_CMD_PARAM_ERR:
1640 case LSC_SCODE_NONPORT:
1641 case LSC_SCODE_LOGGED_IN:
1642 case LSC_SCODE_NOFLOGI_ACC:
1643 default:
1644 mb[0] = MBS_COMMAND_ERROR;
1645 break;
1646 }
1647 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001648 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001649
1650 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1651
1652 mb[0] = MBS_COMMAND_COMPLETE;
1653 mb[1] = 0;
1654 if (iop[0] & BIT_4) {
1655 if (iop[0] & BIT_8)
1656 mb[1] |= BIT_1;
1657 } else
1658 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001659
1660 /* Passback COS information. */
1661 mb[10] = 0;
1662 if (lg->io_parameter[7] || lg->io_parameter[8])
1663 mb[10] |= BIT_0; /* Class 2. */
1664 if (lg->io_parameter[9] || lg->io_parameter[10])
1665 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001666 }
1667
1668 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1669
1670 return rval;
1671}
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673/*
1674 * qla2x00_login_fabric
1675 * Issue login fabric port mailbox command.
1676 *
1677 * Input:
1678 * ha = adapter block pointer.
1679 * loop_id = device loop ID.
1680 * domain = device domain.
1681 * area = device area.
1682 * al_pa = device AL_PA.
1683 * status = pointer for return status.
1684 * opt = command options.
1685 * TARGET_QUEUE_LOCK must be released.
1686 * ADAPTER_STATE_LOCK must be released.
1687 *
1688 * Returns:
1689 * qla2x00 local function return status code.
1690 *
1691 * Context:
1692 * Kernel context.
1693 */
1694int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001695qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1697{
1698 int rval;
1699 mbx_cmd_t mc;
1700 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001701 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001703 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
1705 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1706 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1707 if (HAS_EXTENDED_IDS(ha)) {
1708 mcp->mb[1] = loop_id;
1709 mcp->mb[10] = opt;
1710 mcp->out_mb |= MBX_10;
1711 } else {
1712 mcp->mb[1] = (loop_id << 8) | opt;
1713 }
1714 mcp->mb[2] = domain;
1715 mcp->mb[3] = area << 8 | al_pa;
1716
1717 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1718 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1719 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001720 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721
1722 /* Return mailbox statuses. */
1723 if (mb != NULL) {
1724 mb[0] = mcp->mb[0];
1725 mb[1] = mcp->mb[1];
1726 mb[2] = mcp->mb[2];
1727 mb[6] = mcp->mb[6];
1728 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001729 /* COS retrieved from Get-Port-Database mailbox command. */
1730 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 }
1732
1733 if (rval != QLA_SUCCESS) {
1734 /* RLU tmp code: need to change main mailbox_command function to
1735 * return ok even when the mailbox completion value is not
1736 * SUCCESS. The caller needs to be responsible to interpret
1737 * the return values of this mailbox command if we're not
1738 * to change too much of the existing code.
1739 */
1740 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1741 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1742 mcp->mb[0] == 0x4006)
1743 rval = QLA_SUCCESS;
1744
1745 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001746 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1747 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1748 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 } else {
1750 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001751 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 }
1753
1754 return rval;
1755}
1756
1757/*
1758 * qla2x00_login_local_device
1759 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001760 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 * Input:
1762 * ha = adapter block pointer.
1763 * loop_id = device loop ID.
1764 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001765 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 * Returns:
1767 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001768 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 * Context:
1770 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001771 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 */
1773int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001774qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 uint16_t *mb_ret, uint8_t opt)
1776{
1777 int rval;
1778 mbx_cmd_t mc;
1779 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001780 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001782 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1783
Andrew Vasqueze4289242007-07-19 15:05:56 -07001784 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001785 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001786 fcport->d_id.b.domain, fcport->d_id.b.area,
1787 fcport->d_id.b.al_pa, mb_ret, opt);
1788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1790 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001791 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001793 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 mcp->mb[2] = opt;
1795 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1796 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1797 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1798 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001799 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800
1801 /* Return mailbox statuses. */
1802 if (mb_ret != NULL) {
1803 mb_ret[0] = mcp->mb[0];
1804 mb_ret[1] = mcp->mb[1];
1805 mb_ret[6] = mcp->mb[6];
1806 mb_ret[7] = mcp->mb[7];
1807 }
1808
1809 if (rval != QLA_SUCCESS) {
1810 /* AV tmp code: need to change main mailbox_command function to
1811 * return ok even when the mailbox completion value is not
1812 * SUCCESS. The caller needs to be responsible to interpret
1813 * the return values of this mailbox command if we're not
1814 * to change too much of the existing code.
1815 */
1816 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1817 rval = QLA_SUCCESS;
1818
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001819 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1820 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1821 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 } else {
1823 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001824 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 }
1826
1827 return (rval);
1828}
1829
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001830int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001831qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001832 uint8_t area, uint8_t al_pa)
1833{
1834 int rval;
1835 struct logio_entry_24xx *lg;
1836 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001837 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001838 struct req_que *req;
1839 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001840
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001841 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001842
1843 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1844 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001845 ql_log(ql_log_warn, vha, 0x106e,
1846 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001847 return QLA_MEMORY_ALLOC_FAILED;
1848 }
1849 memset(lg, 0, sizeof(struct logio_entry_24xx));
1850
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001851 if (ql2xmaxqueues > 1)
1852 req = ha->req_q_map[0];
1853 else
1854 req = vha->req;
1855 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001856 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1857 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001858 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001859 lg->nport_handle = cpu_to_le16(loop_id);
1860 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001861 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1862 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001863 lg->port_id[0] = al_pa;
1864 lg->port_id[1] = area;
1865 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001866 lg->vp_index = vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001867
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001868 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001869 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001870 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1871 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001872 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001873 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1874 "Failed to complete IOCB -- error status (%x).\n",
1875 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001876 rval = QLA_FUNCTION_FAILED;
1877 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001878 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1879 "Failed to complete IOCB -- completion status (%x) "
1880 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001881 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001882 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001883 } else {
1884 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001885 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001886 }
1887
1888 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1889
1890 return rval;
1891}
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893/*
1894 * qla2x00_fabric_logout
1895 * Issue logout fabric port mailbox command.
1896 *
1897 * Input:
1898 * ha = adapter block pointer.
1899 * loop_id = device loop ID.
1900 * TARGET_QUEUE_LOCK must be released.
1901 * ADAPTER_STATE_LOCK must be released.
1902 *
1903 * Returns:
1904 * qla2x00 local function return status code.
1905 *
1906 * Context:
1907 * Kernel context.
1908 */
1909int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001910qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001911 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912{
1913 int rval;
1914 mbx_cmd_t mc;
1915 mbx_cmd_t *mcp = &mc;
1916
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001917 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918
1919 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1920 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001921 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 mcp->mb[1] = loop_id;
1923 mcp->mb[10] = 0;
1924 mcp->out_mb |= MBX_10;
1925 } else {
1926 mcp->mb[1] = loop_id << 8;
1927 }
1928
1929 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001930 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001932 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 if (rval != QLA_SUCCESS) {
1935 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001936 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1937 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 } else {
1939 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001940 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 }
1942
1943 return rval;
1944}
1945
1946/*
1947 * qla2x00_full_login_lip
1948 * Issue full login LIP mailbox command.
1949 *
1950 * Input:
1951 * ha = adapter block pointer.
1952 * TARGET_QUEUE_LOCK must be released.
1953 * ADAPTER_STATE_LOCK must be released.
1954 *
1955 * Returns:
1956 * qla2x00 local function return status code.
1957 *
1958 * Context:
1959 * Kernel context.
1960 */
1961int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001962qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963{
1964 int rval;
1965 mbx_cmd_t mc;
1966 mbx_cmd_t *mcp = &mc;
1967
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001968 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
1970 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001971 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001972 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 mcp->mb[3] = 0;
1974 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1975 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001976 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001978 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
1980 if (rval != QLA_SUCCESS) {
1981 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001982 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
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, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986 }
1987
1988 return rval;
1989}
1990
1991/*
1992 * qla2x00_get_id_list
1993 *
1994 * Input:
1995 * ha = adapter block pointer.
1996 *
1997 * Returns:
1998 * qla2x00 local function return status code.
1999 *
2000 * Context:
2001 * Kernel context.
2002 */
2003int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002004qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 uint16_t *entries)
2006{
2007 int rval;
2008 mbx_cmd_t mc;
2009 mbx_cmd_t *mcp = &mc;
2010
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002011 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012
2013 if (id_list == NULL)
2014 return QLA_FUNCTION_FAILED;
2015
2016 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002017 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002018 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002019 mcp->mb[2] = MSW(id_list_dma);
2020 mcp->mb[3] = LSW(id_list_dma);
2021 mcp->mb[6] = MSW(MSD(id_list_dma));
2022 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002023 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002024 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002025 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002026 } else {
2027 mcp->mb[1] = MSW(id_list_dma);
2028 mcp->mb[2] = LSW(id_list_dma);
2029 mcp->mb[3] = MSW(MSD(id_list_dma));
2030 mcp->mb[6] = LSW(MSD(id_list_dma));
2031 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2032 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002034 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002036 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037
2038 if (rval != QLA_SUCCESS) {
2039 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002040 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 } else {
2042 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002043 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 }
2045
2046 return rval;
2047}
2048
2049/*
2050 * qla2x00_get_resource_cnts
2051 * Get current firmware resource counts.
2052 *
2053 * Input:
2054 * ha = adapter block pointer.
2055 *
2056 * Returns:
2057 * qla2x00 local function return status code.
2058 *
2059 * Context:
2060 * Kernel context.
2061 */
2062int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002063qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002064 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002065 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066{
2067 int rval;
2068 mbx_cmd_t mc;
2069 mbx_cmd_t *mcp = &mc;
2070
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002071 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072
2073 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2074 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002075 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002076 if (IS_QLA81XX(vha->hw))
2077 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002078 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002080 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
2082 if (rval != QLA_SUCCESS) {
2083 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002084 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2085 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002087 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2088 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2089 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2090 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2091 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 if (cur_xchg_cnt)
2094 *cur_xchg_cnt = mcp->mb[3];
2095 if (orig_xchg_cnt)
2096 *orig_xchg_cnt = mcp->mb[6];
2097 if (cur_iocb_cnt)
2098 *cur_iocb_cnt = mcp->mb[7];
2099 if (orig_iocb_cnt)
2100 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002101 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002102 *max_npiv_vports = mcp->mb[11];
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002103 if (IS_QLA81XX(vha->hw) && max_fcfs)
2104 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 }
2106
2107 return (rval);
2108}
2109
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110/*
2111 * qla2x00_get_fcal_position_map
2112 * Get FCAL (LILP) position map using mailbox command
2113 *
2114 * Input:
2115 * ha = adapter state pointer.
2116 * pos_map = buffer pointer (can be NULL).
2117 *
2118 * Returns:
2119 * qla2x00 local function return status code.
2120 *
2121 * Context:
2122 * Kernel context.
2123 */
2124int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002125qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126{
2127 int rval;
2128 mbx_cmd_t mc;
2129 mbx_cmd_t *mcp = &mc;
2130 char *pmap;
2131 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002132 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002134 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2135
Andrew Vasquez4b892582008-09-11 21:22:48 -07002136 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002138 ql_log(ql_log_warn, vha, 0x1080,
2139 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140 return QLA_MEMORY_ALLOC_FAILED;
2141 }
2142 memset(pmap, 0, FCAL_MAP_SIZE);
2143
2144 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2145 mcp->mb[2] = MSW(pmap_dma);
2146 mcp->mb[3] = LSW(pmap_dma);
2147 mcp->mb[6] = MSW(MSD(pmap_dma));
2148 mcp->mb[7] = LSW(MSD(pmap_dma));
2149 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2150 mcp->in_mb = MBX_1|MBX_0;
2151 mcp->buf_size = FCAL_MAP_SIZE;
2152 mcp->flags = MBX_DMA_IN;
2153 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002154 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155
2156 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002157 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2158 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2159 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2160 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2161 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162
2163 if (pos_map)
2164 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2165 }
2166 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2167
2168 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002169 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002171 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002172 }
2173
2174 return rval;
2175}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002176
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002177/*
2178 * qla2x00_get_link_status
2179 *
2180 * Input:
2181 * ha = adapter block pointer.
2182 * loop_id = device loop ID.
2183 * ret_buf = pointer to link status return buffer.
2184 *
2185 * Returns:
2186 * 0 = success.
2187 * BIT_0 = mem alloc error.
2188 * BIT_1 = mailbox error.
2189 */
2190int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002191qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002192 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002193{
2194 int rval;
2195 mbx_cmd_t mc;
2196 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002197 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002198 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002199
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002200 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002201
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002202 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002203 mcp->mb[2] = MSW(stats_dma);
2204 mcp->mb[3] = LSW(stats_dma);
2205 mcp->mb[6] = MSW(MSD(stats_dma));
2206 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002207 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2208 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002209 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002210 mcp->mb[1] = loop_id;
2211 mcp->mb[4] = 0;
2212 mcp->mb[10] = 0;
2213 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2214 mcp->in_mb |= MBX_1;
2215 } else if (HAS_EXTENDED_IDS(ha)) {
2216 mcp->mb[1] = loop_id;
2217 mcp->mb[10] = 0;
2218 mcp->out_mb |= MBX_10|MBX_1;
2219 } else {
2220 mcp->mb[1] = loop_id << 8;
2221 mcp->out_mb |= MBX_1;
2222 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002223 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002224 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002225 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002226
2227 if (rval == QLA_SUCCESS) {
2228 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002229 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2230 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002231 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002232 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002233 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002234 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002235 dwords = offsetof(struct link_statistics, unused1) / 4;
2236 siter = diter = &stats->link_fail_cnt;
2237 while (dwords--)
2238 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002239 }
2240 } else {
2241 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002242 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002243 }
2244
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002245 return rval;
2246}
2247
2248int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002249qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002250 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002251{
2252 int rval;
2253 mbx_cmd_t mc;
2254 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002255 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002256
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002257 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002258
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002259 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002260 mcp->mb[2] = MSW(stats_dma);
2261 mcp->mb[3] = LSW(stats_dma);
2262 mcp->mb[6] = MSW(MSD(stats_dma));
2263 mcp->mb[7] = LSW(MSD(stats_dma));
2264 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002265 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002266 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002267 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 -07002268 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002269 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002270 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002271 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002272
2273 if (rval == QLA_SUCCESS) {
2274 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002275 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2276 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002277 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002278 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002279 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002280 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002281 dwords = sizeof(struct link_statistics) / 4;
2282 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002283 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002284 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002285 }
2286 } else {
2287 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002288 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002289 }
2290
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002291 return rval;
2292}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002293
2294int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002295qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002296{
2297 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002298 unsigned long flags = 0;
2299
2300 struct abort_entry_24xx *abt;
2301 dma_addr_t abt_dma;
2302 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002303 fc_port_t *fcport = sp->fcport;
2304 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002305 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002306 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002308 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002309
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002310 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002311 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002312 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002313 break;
2314 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002315 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002316 if (handle == MAX_OUTSTANDING_COMMANDS) {
2317 /* Command not found. */
2318 return QLA_FUNCTION_FAILED;
2319 }
2320
2321 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2322 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002323 ql_log(ql_log_warn, vha, 0x108d,
2324 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002325 return QLA_MEMORY_ALLOC_FAILED;
2326 }
2327 memset(abt, 0, sizeof(struct abort_entry_24xx));
2328
2329 abt->entry_type = ABORT_IOCB_TYPE;
2330 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002331 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002332 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002333 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334 abt->port_id[0] = fcport->d_id.b.al_pa;
2335 abt->port_id[1] = fcport->d_id.b.area;
2336 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002337 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002338
2339 abt->req_que_no = cpu_to_le16(req->id);
2340
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002341 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002342 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002343 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2344 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002345 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002346 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2347 "Failed to complete IOCB -- error status (%x).\n",
2348 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002349 rval = QLA_FUNCTION_FAILED;
2350 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002351 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2352 "Failed to complete IOCB -- completion status (%x).\n",
2353 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002354 rval = QLA_FUNCTION_FAILED;
2355 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002356 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002357 }
2358
2359 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2360
2361 return rval;
2362}
2363
2364struct tsk_mgmt_cmd {
2365 union {
2366 struct tsk_mgmt_entry tsk;
2367 struct sts_entry_24xx sts;
2368 } p;
2369};
2370
Andrew Vasquez523ec772008-04-03 13:13:24 -07002371static int
2372__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002373 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002374{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002375 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002376 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002377 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002378 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002379 scsi_qla_host_t *vha;
2380 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002381 struct req_que *req;
2382 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002383
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002384 vha = fcport->vha;
2385 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002386 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002387
2388 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2389
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002390 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002391 rsp = ha->rsp_q_map[tag + 1];
2392 else
2393 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002394 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002395 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002396 ql_log(ql_log_warn, vha, 0x1093,
2397 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002398 return QLA_MEMORY_ALLOC_FAILED;
2399 }
2400 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2401
2402 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2403 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002404 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002405 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002406 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002407 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002408 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2409 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2410 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002411 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002412 if (type == TCF_LUN_RESET) {
2413 int_to_scsilun(l, &tsk->p.tsk.lun);
2414 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2415 sizeof(tsk->p.tsk.lun));
2416 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002417
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002418 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002419 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002420 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002421 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2422 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002423 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002424 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2425 "Failed to complete IOCB -- error status (%x).\n",
2426 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002427 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002428 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002429 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002430 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2431 "Failed to complete IOCB -- completion status (%x).\n",
2432 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002433 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002434 } else if (le16_to_cpu(sts->scsi_status) &
2435 SS_RESPONSE_INFO_LEN_VALID) {
2436 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002437 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2438 "Ignoring inconsistent data length -- not enough "
2439 "response info (%d).\n",
2440 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002441 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002442 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2443 "Failed to complete IOCB -- response (%x).\n",
2444 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002445 rval = QLA_FUNCTION_FAILED;
2446 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002447 }
2448
2449 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002450 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002451 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2452 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002453 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2454 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002455 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002456 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002457 }
2458
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002459 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002460
2461 return rval;
2462}
2463
Andrew Vasquez523ec772008-04-03 13:13:24 -07002464int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002465qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002466{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002467 struct qla_hw_data *ha = fcport->vha->hw;
2468
2469 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2470 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2471
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002472 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002473}
2474
2475int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002476qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002477{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002478 struct qla_hw_data *ha = fcport->vha->hw;
2479
2480 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2481 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2482
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002483 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002484}
2485
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002486int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002487qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002488{
2489 int rval;
2490 mbx_cmd_t mc;
2491 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002492 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002493
Andrew Vasquez68af0812008-05-12 22:21:13 -07002494 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002495 return QLA_FUNCTION_FAILED;
2496
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002497 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002498
2499 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2500 mcp->out_mb = MBX_0;
2501 mcp->in_mb = MBX_0;
2502 mcp->tov = 5;
2503 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002504 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002505
2506 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002507 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002508 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002509 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002510 }
2511
2512 return rval;
2513}
2514
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002515/**
2516 * qla2x00_set_serdes_params() -
2517 * @ha: HA context
2518 *
2519 * Returns
2520 */
2521int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002522qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002523 uint16_t sw_em_2g, uint16_t sw_em_4g)
2524{
2525 int rval;
2526 mbx_cmd_t mc;
2527 mbx_cmd_t *mcp = &mc;
2528
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002529 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002530
2531 mcp->mb[0] = MBC_SERDES_PARAMS;
2532 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002533 mcp->mb[2] = sw_em_1g | BIT_15;
2534 mcp->mb[3] = sw_em_2g | BIT_15;
2535 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002536 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2537 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002538 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002539 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002540 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002541
2542 if (rval != QLA_SUCCESS) {
2543 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002544 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2545 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002546 } else {
2547 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002548 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002549 }
2550
2551 return rval;
2552}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002553
2554int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002555qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002556{
2557 int rval;
2558 mbx_cmd_t mc;
2559 mbx_cmd_t *mcp = &mc;
2560
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002561 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002562 return QLA_FUNCTION_FAILED;
2563
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002564 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002565
2566 mcp->mb[0] = MBC_STOP_FIRMWARE;
2567 mcp->out_mb = MBX_0;
2568 mcp->in_mb = MBX_0;
2569 mcp->tov = 5;
2570 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002571 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002572
2573 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002574 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002575 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2576 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002577 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002578 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002579 }
2580
2581 return rval;
2582}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002583
2584int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002585qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002586 uint16_t buffers)
2587{
2588 int rval;
2589 mbx_cmd_t mc;
2590 mbx_cmd_t *mcp = &mc;
2591
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002592 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2593
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002594 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002595 return QLA_FUNCTION_FAILED;
2596
Andrew Vasquez85880802009-12-15 21:29:46 -08002597 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2598 return QLA_FUNCTION_FAILED;
2599
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002600 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002601 mcp->mb[1] = TC_EFT_ENABLE;
2602 mcp->mb[2] = LSW(eft_dma);
2603 mcp->mb[3] = MSW(eft_dma);
2604 mcp->mb[4] = LSW(MSD(eft_dma));
2605 mcp->mb[5] = MSW(MSD(eft_dma));
2606 mcp->mb[6] = buffers;
2607 mcp->mb[7] = TC_AEN_DISABLE;
2608 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 -07002609 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002610 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002611 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002612 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002613 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002614 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2615 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2616 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002617 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002618 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002619 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002620
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002621 return rval;
2622}
2623
2624int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002625qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002626{
2627 int rval;
2628 mbx_cmd_t mc;
2629 mbx_cmd_t *mcp = &mc;
2630
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002631 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2632
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002633 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002634 return QLA_FUNCTION_FAILED;
2635
Andrew Vasquez85880802009-12-15 21:29:46 -08002636 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2637 return QLA_FUNCTION_FAILED;
2638
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002639 mcp->mb[0] = MBC_TRACE_CONTROL;
2640 mcp->mb[1] = TC_EFT_DISABLE;
2641 mcp->out_mb = MBX_1|MBX_0;
2642 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002643 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002644 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002645 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002646 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002647 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2648 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2649 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002650 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002651 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002652 }
2653
2654 return rval;
2655}
2656
Andrew Vasquez88729e52006-06-23 16:10:50 -07002657int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002658qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002659 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2660{
2661 int rval;
2662 mbx_cmd_t mc;
2663 mbx_cmd_t *mcp = &mc;
2664
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002665 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2666
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002667 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002668 return QLA_FUNCTION_FAILED;
2669
Andrew Vasquez85880802009-12-15 21:29:46 -08002670 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2671 return QLA_FUNCTION_FAILED;
2672
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002673 mcp->mb[0] = MBC_TRACE_CONTROL;
2674 mcp->mb[1] = TC_FCE_ENABLE;
2675 mcp->mb[2] = LSW(fce_dma);
2676 mcp->mb[3] = MSW(fce_dma);
2677 mcp->mb[4] = LSW(MSD(fce_dma));
2678 mcp->mb[5] = MSW(MSD(fce_dma));
2679 mcp->mb[6] = buffers;
2680 mcp->mb[7] = TC_AEN_DISABLE;
2681 mcp->mb[8] = 0;
2682 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2683 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2684 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2685 MBX_1|MBX_0;
2686 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002687 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002688 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002689 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002690 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002691 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2692 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2693 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002694 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002695 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002696
2697 if (mb)
2698 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2699 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002700 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002701 }
2702
2703 return rval;
2704}
2705
2706int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002707qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002708{
2709 int rval;
2710 mbx_cmd_t mc;
2711 mbx_cmd_t *mcp = &mc;
2712
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002713 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2714
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002715 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002716 return QLA_FUNCTION_FAILED;
2717
Andrew Vasquez85880802009-12-15 21:29:46 -08002718 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2719 return QLA_FUNCTION_FAILED;
2720
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002721 mcp->mb[0] = MBC_TRACE_CONTROL;
2722 mcp->mb[1] = TC_FCE_DISABLE;
2723 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2724 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2725 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2726 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002727 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002728 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002729 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002730 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002731 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2732 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2733 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002734 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002735 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002736
2737 if (wr)
2738 *wr = (uint64_t) mcp->mb[5] << 48 |
2739 (uint64_t) mcp->mb[4] << 32 |
2740 (uint64_t) mcp->mb[3] << 16 |
2741 (uint64_t) mcp->mb[2];
2742 if (rd)
2743 *rd = (uint64_t) mcp->mb[9] << 48 |
2744 (uint64_t) mcp->mb[8] << 32 |
2745 (uint64_t) mcp->mb[7] << 16 |
2746 (uint64_t) mcp->mb[6];
2747 }
2748
2749 return rval;
2750}
2751
2752int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002753qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2754 uint16_t *port_speed, uint16_t *mb)
2755{
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, 0x10b0, "Entered %s.\n", __func__);
2761
Giridhar Malavali6e980162010-03-19 17:03:58 -07002762 if (!IS_IIDMA_CAPABLE(vha->hw))
2763 return QLA_FUNCTION_FAILED;
2764
Giridhar Malavali6e980162010-03-19 17:03:58 -07002765 mcp->mb[0] = MBC_PORT_PARAMS;
2766 mcp->mb[1] = loop_id;
2767 mcp->mb[2] = mcp->mb[3] = 0;
2768 mcp->mb[9] = vha->vp_idx;
2769 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2770 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2771 mcp->tov = MBX_TOV_SECONDS;
2772 mcp->flags = 0;
2773 rval = qla2x00_mailbox_command(vha, mcp);
2774
2775 /* Return mailbox statuses. */
2776 if (mb != NULL) {
2777 mb[0] = mcp->mb[0];
2778 mb[1] = mcp->mb[1];
2779 mb[3] = mcp->mb[3];
2780 }
2781
2782 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002783 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002784 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002785 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002786 if (port_speed)
2787 *port_speed = mcp->mb[3];
2788 }
2789
2790 return rval;
2791}
2792
2793int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002794qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002795 uint16_t port_speed, uint16_t *mb)
2796{
2797 int rval;
2798 mbx_cmd_t mc;
2799 mbx_cmd_t *mcp = &mc;
2800
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002801 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2802
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002803 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002804 return QLA_FUNCTION_FAILED;
2805
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002806 mcp->mb[0] = MBC_PORT_PARAMS;
2807 mcp->mb[1] = loop_id;
2808 mcp->mb[2] = BIT_0;
Giridhar Malavalia9083012010-04-12 17:59:55 -07002809 if (IS_QLA8XXX_TYPE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002810 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2811 else
2812 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2813 mcp->mb[9] = vha->vp_idx;
2814 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2815 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002816 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002817 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002818 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002819
2820 /* Return mailbox statuses. */
2821 if (mb != NULL) {
2822 mb[0] = mcp->mb[0];
2823 mb[1] = mcp->mb[1];
2824 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002825 }
2826
2827 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002828 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002829 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002830 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002831 }
2832
2833 return rval;
2834}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002835
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002836void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002837qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002838 struct vp_rpt_id_entry_24xx *rptid_entry)
2839{
2840 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002841 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002842 struct qla_hw_data *ha = vha->hw;
2843 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002844 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002845
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002846 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2847
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002848 if (rptid_entry->entry_status != 0)
2849 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002850
2851 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002852 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2853 "Format 0 : Number of VPs setup %d, number of "
2854 "VPs acquired %d.\n",
2855 MSB(le16_to_cpu(rptid_entry->vp_count)),
2856 LSB(le16_to_cpu(rptid_entry->vp_count)));
2857 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2858 "Primary port id %02x%02x%02x.\n",
2859 rptid_entry->port_id[2], rptid_entry->port_id[1],
2860 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002861 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002862 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002863 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2864 "Format 1: VP[%d] enabled - status %d - with "
2865 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002866 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002867 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002868
2869 vp = vha;
2870 if (vp_idx == 0 && (MSB(stat) != 1))
2871 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002872
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002873 if (MSB(stat) == 1) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002874 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2875 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002876 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002877 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002878
Arun Easifeafb7b2010-09-03 14:57:00 -07002879 spin_lock_irqsave(&ha->vport_slock, flags);
2880 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002881 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002882 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002883 spin_unlock_irqrestore(&ha->vport_slock, flags);
2884
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002885 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002886 return;
2887
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002888 vp->d_id.b.domain = rptid_entry->port_id[2];
2889 vp->d_id.b.area = rptid_entry->port_id[1];
2890 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002891
2892 /*
2893 * Cannot configure here as we are still sitting on the
2894 * response queue. Handle it in dpc context.
2895 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002896 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002897
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002898reg_needed:
2899 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2900 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2901 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002902 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002903 }
2904}
2905
2906/*
2907 * qla24xx_modify_vp_config
2908 * Change VP configuration for vha
2909 *
2910 * Input:
2911 * vha = adapter block pointer.
2912 *
2913 * Returns:
2914 * qla2xxx local function return status code.
2915 *
2916 * Context:
2917 * Kernel context.
2918 */
2919int
2920qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2921{
2922 int rval;
2923 struct vp_config_entry_24xx *vpmod;
2924 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002925 struct qla_hw_data *ha = vha->hw;
2926 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002927
2928 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002929
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002930 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2931
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002932 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002933 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002934 ql_log(ql_log_warn, vha, 0x10bc,
2935 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002936 return QLA_MEMORY_ALLOC_FAILED;
2937 }
2938
2939 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2940 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2941 vpmod->entry_count = 1;
2942 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2943 vpmod->vp_count = 1;
2944 vpmod->vp_index1 = vha->vp_idx;
2945 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2946 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2947 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2948 vpmod->entry_count = 1;
2949
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002950 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002951 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002952 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
2953 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002954 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002955 ql_dbg(ql_dbg_mbx, vha, 0x10be,
2956 "Failed to complete IOCB -- error status (%x).\n",
2957 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002958 rval = QLA_FUNCTION_FAILED;
2959 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002960 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
2961 "Failed to complete IOCB -- completion status (%x).\n",
2962 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002963 rval = QLA_FUNCTION_FAILED;
2964 } else {
2965 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002966 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002967 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
2968 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002969 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002970
2971 return rval;
2972}
2973
2974/*
2975 * qla24xx_control_vp
2976 * Enable a virtual port for given host
2977 *
2978 * Input:
2979 * ha = adapter block pointer.
2980 * vhba = virtual adapter (unused)
2981 * index = index number for enabled VP
2982 *
2983 * Returns:
2984 * qla2xxx local function return status code.
2985 *
2986 * Context:
2987 * Kernel context.
2988 */
2989int
2990qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
2991{
2992 int rval;
2993 int map, pos;
2994 struct vp_ctrl_entry_24xx *vce;
2995 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002996 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002997 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002998 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002999
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003000 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3001 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003002
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003003 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003004 return QLA_PARAMETER_ERROR;
3005
3006 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3007 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003008 ql_log(ql_log_warn, vha, 0x10c2,
3009 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003010 return QLA_MEMORY_ALLOC_FAILED;
3011 }
3012 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3013
3014 vce->entry_type = VP_CTRL_IOCB_TYPE;
3015 vce->entry_count = 1;
3016 vce->command = cpu_to_le16(cmd);
3017 vce->vp_count = __constant_cpu_to_le16(1);
3018
3019 /* index map in firmware starts with 1; decrement index
3020 * this is ok as we never use index 0
3021 */
3022 map = (vp_index - 1) / 8;
3023 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003024 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003025 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003026 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003027
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003028 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003029 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003030 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3031 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003032 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003033 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3034 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003035 vce->entry_status);
3036 rval = QLA_FUNCTION_FAILED;
3037 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003038 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3039 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003040 le16_to_cpu(vce->comp_status));
3041 rval = QLA_FUNCTION_FAILED;
3042 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003043 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003044 }
3045
3046 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3047
3048 return rval;
3049}
3050
3051/*
3052 * qla2x00_send_change_request
3053 * Receive or disable RSCN request from fabric controller
3054 *
3055 * Input:
3056 * ha = adapter block pointer
3057 * format = registration format:
3058 * 0 - Reserved
3059 * 1 - Fabric detected registration
3060 * 2 - N_port detected registration
3061 * 3 - Full registration
3062 * FF - clear registration
3063 * vp_idx = Virtual port index
3064 *
3065 * Returns:
3066 * qla2x00 local function return status code.
3067 *
3068 * Context:
3069 * Kernel Context
3070 */
3071
3072int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003073qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003074 uint16_t vp_idx)
3075{
3076 int rval;
3077 mbx_cmd_t mc;
3078 mbx_cmd_t *mcp = &mc;
3079
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003080 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3081
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003082 /*
3083 * This command is implicitly executed by firmware during login for the
3084 * physical hosts
3085 */
3086 if (vp_idx == 0)
3087 return QLA_FUNCTION_FAILED;
3088
3089 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3090 mcp->mb[1] = format;
3091 mcp->mb[9] = vp_idx;
3092 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3093 mcp->in_mb = MBX_0|MBX_1;
3094 mcp->tov = MBX_TOV_SECONDS;
3095 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003096 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003097
3098 if (rval == QLA_SUCCESS) {
3099 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3100 rval = BIT_1;
3101 }
3102 } else
3103 rval = BIT_1;
3104
3105 return rval;
3106}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003107
3108int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003109qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003110 uint32_t size)
3111{
3112 int rval;
3113 mbx_cmd_t mc;
3114 mbx_cmd_t *mcp = &mc;
3115
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003116 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003117
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003118 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003119 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3120 mcp->mb[8] = MSW(addr);
3121 mcp->out_mb = MBX_8|MBX_0;
3122 } else {
3123 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3124 mcp->out_mb = MBX_0;
3125 }
3126 mcp->mb[1] = LSW(addr);
3127 mcp->mb[2] = MSW(req_dma);
3128 mcp->mb[3] = LSW(req_dma);
3129 mcp->mb[6] = MSW(MSD(req_dma));
3130 mcp->mb[7] = LSW(MSD(req_dma));
3131 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003132 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003133 mcp->mb[4] = MSW(size);
3134 mcp->mb[5] = LSW(size);
3135 mcp->out_mb |= MBX_5|MBX_4;
3136 } else {
3137 mcp->mb[4] = LSW(size);
3138 mcp->out_mb |= MBX_4;
3139 }
3140
3141 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003142 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003143 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003144 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003145
3146 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003147 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3148 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003149 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003150 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003151 }
3152
3153 return rval;
3154}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003155
3156/* 84XX Support **************************************************************/
3157
3158struct cs84xx_mgmt_cmd {
3159 union {
3160 struct verify_chip_entry_84xx req;
3161 struct verify_chip_rsp_84xx rsp;
3162 } p;
3163};
3164
3165int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003166qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003167{
3168 int rval, retry;
3169 struct cs84xx_mgmt_cmd *mn;
3170 dma_addr_t mn_dma;
3171 uint16_t options;
3172 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003173 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003174
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003175 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003176
3177 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3178 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003179 return QLA_MEMORY_ALLOC_FAILED;
3180 }
3181
3182 /* Force Update? */
3183 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3184 /* Diagnostic firmware? */
3185 /* options |= MENLO_DIAG_FW; */
3186 /* We update the firmware with only one data sequence. */
3187 options |= VCO_END_OF_DATA;
3188
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003189 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003190 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003191 memset(mn, 0, sizeof(*mn));
3192 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3193 mn->p.req.entry_count = 1;
3194 mn->p.req.options = cpu_to_le16(options);
3195
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003196 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3197 "Dump of Verify Request.\n");
3198 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3199 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003200
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003201 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003202 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003203 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3204 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003205 goto verify_done;
3206 }
3207
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003208 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3209 "Dump of Verify Response.\n");
3210 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3211 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003212
3213 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3214 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3215 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003216 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3217 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003218
3219 if (status[0] != CS_COMPLETE) {
3220 rval = QLA_FUNCTION_FAILED;
3221 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003222 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3223 "Firmware update failed. Retrying "
3224 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003225 options |= VCO_DONT_UPDATE_FW;
3226 options &= ~VCO_FORCE_UPDATE;
3227 retry = 1;
3228 }
3229 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003230 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3231 "Firmware updated to %x.\n",
3232 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003233
3234 /* NOTE: we only update OP firmware. */
3235 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3236 ha->cs84xx->op_fw_version =
3237 le32_to_cpu(mn->p.rsp.fw_ver);
3238 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3239 flags);
3240 }
3241 } while (retry);
3242
3243verify_done:
3244 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3245
3246 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003247 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003248 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003249 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003250 }
3251
3252 return rval;
3253}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003254
3255int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003256qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003257{
3258 int rval;
3259 unsigned long flags;
3260 mbx_cmd_t mc;
3261 mbx_cmd_t *mcp = &mc;
3262 struct device_reg_25xxmq __iomem *reg;
3263 struct qla_hw_data *ha = vha->hw;
3264
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003265 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3266
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003267 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003268 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003269 mcp->mb[2] = MSW(LSD(req->dma));
3270 mcp->mb[3] = LSW(LSD(req->dma));
3271 mcp->mb[6] = MSW(MSD(req->dma));
3272 mcp->mb[7] = LSW(MSD(req->dma));
3273 mcp->mb[5] = req->length;
3274 if (req->rsp)
3275 mcp->mb[10] = req->rsp->id;
3276 mcp->mb[12] = req->qos;
3277 mcp->mb[11] = req->vp_idx;
3278 mcp->mb[13] = req->rid;
3279
3280 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3281 QLA_QUE_PAGE * req->id);
3282
3283 mcp->mb[4] = req->id;
3284 /* que in ptr index */
3285 mcp->mb[8] = 0;
3286 /* que out ptr index */
3287 mcp->mb[9] = 0;
3288 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3289 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3290 mcp->in_mb = MBX_0;
3291 mcp->flags = MBX_DMA_OUT;
3292 mcp->tov = 60;
3293
3294 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003295 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003296 WRT_REG_DWORD(&reg->req_q_in, 0);
3297 WRT_REG_DWORD(&reg->req_q_out, 0);
3298 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003299 req->req_q_in = &reg->req_q_in;
3300 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003301 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3302
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003303 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003304 if (rval != QLA_SUCCESS) {
3305 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3306 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3307 } else {
3308 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3309 }
3310
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003311 return rval;
3312}
3313
3314int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003315qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003316{
3317 int rval;
3318 unsigned long flags;
3319 mbx_cmd_t mc;
3320 mbx_cmd_t *mcp = &mc;
3321 struct device_reg_25xxmq __iomem *reg;
3322 struct qla_hw_data *ha = vha->hw;
3323
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003324 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3325
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003326 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003327 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003328 mcp->mb[2] = MSW(LSD(rsp->dma));
3329 mcp->mb[3] = LSW(LSD(rsp->dma));
3330 mcp->mb[6] = MSW(MSD(rsp->dma));
3331 mcp->mb[7] = LSW(MSD(rsp->dma));
3332 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003333 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003334 mcp->mb[13] = rsp->rid;
3335
3336 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3337 QLA_QUE_PAGE * rsp->id);
3338
3339 mcp->mb[4] = rsp->id;
3340 /* que in ptr index */
3341 mcp->mb[8] = 0;
3342 /* que out ptr index */
3343 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003344 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003345 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3346 mcp->in_mb = MBX_0;
3347 mcp->flags = MBX_DMA_OUT;
3348 mcp->tov = 60;
3349
3350 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003351 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003352 WRT_REG_DWORD(&reg->rsp_q_out, 0);
3353 WRT_REG_DWORD(&reg->rsp_q_in, 0);
3354 }
3355
3356 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3357
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003358 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003359 if (rval != QLA_SUCCESS) {
3360 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3361 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3362 } else {
3363 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3364 }
3365
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003366 return rval;
3367}
3368
Andrew Vasquez8a659572009-02-08 20:50:12 -08003369int
3370qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3371{
3372 int rval;
3373 mbx_cmd_t mc;
3374 mbx_cmd_t *mcp = &mc;
3375
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003376 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003377
3378 mcp->mb[0] = MBC_IDC_ACK;
3379 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3380 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3381 mcp->in_mb = MBX_0;
3382 mcp->tov = MBX_TOV_SECONDS;
3383 mcp->flags = 0;
3384 rval = qla2x00_mailbox_command(vha, mcp);
3385
3386 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003387 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3388 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003389 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003390 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003391 }
3392
3393 return rval;
3394}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003395
3396int
3397qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3398{
3399 int rval;
3400 mbx_cmd_t mc;
3401 mbx_cmd_t *mcp = &mc;
3402
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003403 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3404
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003405 if (!IS_QLA81XX(vha->hw))
3406 return QLA_FUNCTION_FAILED;
3407
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003408 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3409 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3410 mcp->out_mb = MBX_1|MBX_0;
3411 mcp->in_mb = MBX_1|MBX_0;
3412 mcp->tov = MBX_TOV_SECONDS;
3413 mcp->flags = 0;
3414 rval = qla2x00_mailbox_command(vha, mcp);
3415
3416 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003417 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3418 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3419 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003420 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003421 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003422 *sector_size = mcp->mb[1];
3423 }
3424
3425 return rval;
3426}
3427
3428int
3429qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3430{
3431 int rval;
3432 mbx_cmd_t mc;
3433 mbx_cmd_t *mcp = &mc;
3434
3435 if (!IS_QLA81XX(vha->hw))
3436 return QLA_FUNCTION_FAILED;
3437
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003438 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003439
3440 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3441 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3442 FAC_OPT_CMD_WRITE_PROTECT;
3443 mcp->out_mb = MBX_1|MBX_0;
3444 mcp->in_mb = MBX_1|MBX_0;
3445 mcp->tov = MBX_TOV_SECONDS;
3446 mcp->flags = 0;
3447 rval = qla2x00_mailbox_command(vha, mcp);
3448
3449 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003450 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3451 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3452 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003453 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003454 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003455 }
3456
3457 return rval;
3458}
3459
3460int
3461qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3462{
3463 int rval;
3464 mbx_cmd_t mc;
3465 mbx_cmd_t *mcp = &mc;
3466
3467 if (!IS_QLA81XX(vha->hw))
3468 return QLA_FUNCTION_FAILED;
3469
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003470 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003471
3472 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3473 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3474 mcp->mb[2] = LSW(start);
3475 mcp->mb[3] = MSW(start);
3476 mcp->mb[4] = LSW(finish);
3477 mcp->mb[5] = MSW(finish);
3478 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3479 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3480 mcp->tov = MBX_TOV_SECONDS;
3481 mcp->flags = 0;
3482 rval = qla2x00_mailbox_command(vha, mcp);
3483
3484 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003485 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3486 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3487 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003488 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003489 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003490 }
3491
3492 return rval;
3493}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003494
3495int
3496qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3497{
3498 int rval = 0;
3499 mbx_cmd_t mc;
3500 mbx_cmd_t *mcp = &mc;
3501
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003502 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003503
3504 mcp->mb[0] = MBC_RESTART_MPI_FW;
3505 mcp->out_mb = MBX_0;
3506 mcp->in_mb = MBX_0|MBX_1;
3507 mcp->tov = MBX_TOV_SECONDS;
3508 mcp->flags = 0;
3509 rval = qla2x00_mailbox_command(vha, mcp);
3510
3511 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003512 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3513 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3514 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003515 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003516 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003517 }
3518
3519 return rval;
3520}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003521
3522int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003523qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3524 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003525{
3526 int rval;
3527 mbx_cmd_t mc;
3528 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003529 struct qla_hw_data *ha = vha->hw;
3530
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003531 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3532
Joe Carnuccio6766df92011-05-10 11:30:15 -07003533 if (!IS_FWI2_CAPABLE(ha))
3534 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003535
Joe Carnuccio6766df92011-05-10 11:30:15 -07003536 if (len == 1)
3537 opt |= BIT_0;
3538
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003539 mcp->mb[0] = MBC_READ_SFP;
3540 mcp->mb[1] = dev;
3541 mcp->mb[2] = MSW(sfp_dma);
3542 mcp->mb[3] = LSW(sfp_dma);
3543 mcp->mb[6] = MSW(MSD(sfp_dma));
3544 mcp->mb[7] = LSW(MSD(sfp_dma));
3545 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003546 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003547 mcp->mb[10] = opt;
3548 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 -07003549 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003550 mcp->tov = MBX_TOV_SECONDS;
3551 mcp->flags = 0;
3552 rval = qla2x00_mailbox_command(vha, mcp);
3553
3554 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003555 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003556
3557 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003558 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3559 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003560 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003561 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003562 }
3563
3564 return rval;
3565}
3566
3567int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003568qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3569 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003570{
3571 int rval;
3572 mbx_cmd_t mc;
3573 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003574 struct qla_hw_data *ha = vha->hw;
3575
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003576 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3577
Joe Carnuccio6766df92011-05-10 11:30:15 -07003578 if (!IS_FWI2_CAPABLE(ha))
3579 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003580
Joe Carnuccio6766df92011-05-10 11:30:15 -07003581 if (len == 1)
3582 opt |= BIT_0;
3583
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003584 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003585 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003586
3587 mcp->mb[0] = MBC_WRITE_SFP;
3588 mcp->mb[1] = dev;
3589 mcp->mb[2] = MSW(sfp_dma);
3590 mcp->mb[3] = LSW(sfp_dma);
3591 mcp->mb[6] = MSW(MSD(sfp_dma));
3592 mcp->mb[7] = LSW(MSD(sfp_dma));
3593 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003594 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003595 mcp->mb[10] = opt;
3596 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 -07003597 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003598 mcp->tov = MBX_TOV_SECONDS;
3599 mcp->flags = 0;
3600 rval = qla2x00_mailbox_command(vha, mcp);
3601
3602 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003603 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3604 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003605 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003606 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003607 }
3608
3609 return rval;
3610}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003611
3612int
3613qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3614 uint16_t size_in_bytes, uint16_t *actual_size)
3615{
3616 int rval;
3617 mbx_cmd_t mc;
3618 mbx_cmd_t *mcp = &mc;
3619
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003620 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3621
Giridhar Malavalia9083012010-04-12 17:59:55 -07003622 if (!IS_QLA8XXX_TYPE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003623 return QLA_FUNCTION_FAILED;
3624
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003625 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3626 mcp->mb[2] = MSW(stats_dma);
3627 mcp->mb[3] = LSW(stats_dma);
3628 mcp->mb[6] = MSW(MSD(stats_dma));
3629 mcp->mb[7] = LSW(MSD(stats_dma));
3630 mcp->mb[8] = size_in_bytes >> 2;
3631 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3632 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3633 mcp->tov = MBX_TOV_SECONDS;
3634 mcp->flags = 0;
3635 rval = qla2x00_mailbox_command(vha, mcp);
3636
3637 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003638 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3639 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3640 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003641 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003642 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3643
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003644
3645 *actual_size = mcp->mb[2] << 2;
3646 }
3647
3648 return rval;
3649}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003650
3651int
3652qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3653 uint16_t size)
3654{
3655 int rval;
3656 mbx_cmd_t mc;
3657 mbx_cmd_t *mcp = &mc;
3658
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003659 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3660
Giridhar Malavalia9083012010-04-12 17:59:55 -07003661 if (!IS_QLA8XXX_TYPE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003662 return QLA_FUNCTION_FAILED;
3663
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003664 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3665 mcp->mb[1] = 0;
3666 mcp->mb[2] = MSW(tlv_dma);
3667 mcp->mb[3] = LSW(tlv_dma);
3668 mcp->mb[6] = MSW(MSD(tlv_dma));
3669 mcp->mb[7] = LSW(MSD(tlv_dma));
3670 mcp->mb[8] = size;
3671 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3672 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3673 mcp->tov = MBX_TOV_SECONDS;
3674 mcp->flags = 0;
3675 rval = qla2x00_mailbox_command(vha, mcp);
3676
3677 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003678 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3679 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3680 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003681 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003682 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003683 }
3684
3685 return rval;
3686}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003687
3688int
3689qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3690{
3691 int rval;
3692 mbx_cmd_t mc;
3693 mbx_cmd_t *mcp = &mc;
3694
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003695 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3696
Andrew Vasquez18e75552009-06-03 09:55:30 -07003697 if (!IS_FWI2_CAPABLE(vha->hw))
3698 return QLA_FUNCTION_FAILED;
3699
Andrew Vasquez18e75552009-06-03 09:55:30 -07003700 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3701 mcp->mb[1] = LSW(risc_addr);
3702 mcp->mb[8] = MSW(risc_addr);
3703 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3704 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3705 mcp->tov = 30;
3706 mcp->flags = 0;
3707 rval = qla2x00_mailbox_command(vha, mcp);
3708 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003709 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3710 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003711 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003712 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003713 *data = mcp->mb[3] << 16 | mcp->mb[2];
3714 }
3715
3716 return rval;
3717}
3718
3719int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003720qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3721 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003722{
3723 int rval;
3724 mbx_cmd_t mc;
3725 mbx_cmd_t *mcp = &mc;
3726 uint32_t iter_cnt = 0x1;
3727
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003728 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003729
3730 memset(mcp->mb, 0 , sizeof(mcp->mb));
3731 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3732 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3733
3734 /* transfer count */
3735 mcp->mb[10] = LSW(mreq->transfer_size);
3736 mcp->mb[11] = MSW(mreq->transfer_size);
3737
3738 /* send data address */
3739 mcp->mb[14] = LSW(mreq->send_dma);
3740 mcp->mb[15] = MSW(mreq->send_dma);
3741 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3742 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3743
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003744 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003745 mcp->mb[16] = LSW(mreq->rcv_dma);
3746 mcp->mb[17] = MSW(mreq->rcv_dma);
3747 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3748 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3749
3750 /* Iteration count */
3751 mcp->mb[18] = LSW(iter_cnt);
3752 mcp->mb[19] = MSW(iter_cnt);
3753
3754 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3755 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003756 if (IS_QLA8XXX_TYPE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003757 mcp->out_mb |= MBX_2;
3758 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3759
3760 mcp->buf_size = mreq->transfer_size;
3761 mcp->tov = MBX_TOV_SECONDS;
3762 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3763
3764 rval = qla2x00_mailbox_command(vha, mcp);
3765
3766 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003767 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3768 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3769 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3770 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003771 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003772 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003773 }
3774
3775 /* Copy mailbox information */
3776 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003777 return rval;
3778}
3779
3780int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003781qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3782 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003783{
3784 int rval;
3785 mbx_cmd_t mc;
3786 mbx_cmd_t *mcp = &mc;
3787 struct qla_hw_data *ha = vha->hw;
3788
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003789 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003790
3791 memset(mcp->mb, 0 , sizeof(mcp->mb));
3792 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3793 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavalia9083012010-04-12 17:59:55 -07003794 if (IS_QLA8XXX_TYPE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003795 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003796 mcp->mb[2] = vha->fcoe_fcf_idx;
3797 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003798 mcp->mb[16] = LSW(mreq->rcv_dma);
3799 mcp->mb[17] = MSW(mreq->rcv_dma);
3800 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3801 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3802
3803 mcp->mb[10] = LSW(mreq->transfer_size);
3804
3805 mcp->mb[14] = LSW(mreq->send_dma);
3806 mcp->mb[15] = MSW(mreq->send_dma);
3807 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3808 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3809
3810 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3811 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003812 if (IS_QLA8XXX_TYPE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003813 mcp->out_mb |= MBX_2;
3814
3815 mcp->in_mb = MBX_0;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003816 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003817 mcp->in_mb |= MBX_1;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003818 if (IS_QLA8XXX_TYPE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003819 mcp->in_mb |= MBX_3;
3820
3821 mcp->tov = MBX_TOV_SECONDS;
3822 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3823 mcp->buf_size = mreq->transfer_size;
3824
3825 rval = qla2x00_mailbox_command(vha, mcp);
3826
3827 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003828 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3829 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3830 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003831 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003832 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003833 }
3834
3835 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003836 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003837 return rval;
3838}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003839
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003840int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003841qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003842{
3843 int rval;
3844 mbx_cmd_t mc;
3845 mbx_cmd_t *mcp = &mc;
3846
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003847 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3848 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003849
3850 mcp->mb[0] = MBC_ISP84XX_RESET;
3851 mcp->mb[1] = enable_diagnostic;
3852 mcp->out_mb = MBX_1|MBX_0;
3853 mcp->in_mb = MBX_1|MBX_0;
3854 mcp->tov = MBX_TOV_SECONDS;
3855 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003856 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003857
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003858 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003859 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003860 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003861 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003862
3863 return rval;
3864}
3865
3866int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003867qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3868{
3869 int rval;
3870 mbx_cmd_t mc;
3871 mbx_cmd_t *mcp = &mc;
3872
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003873 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3874
Andrew Vasquez18e75552009-06-03 09:55:30 -07003875 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003876 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003877
Andrew Vasquez18e75552009-06-03 09:55:30 -07003878 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3879 mcp->mb[1] = LSW(risc_addr);
3880 mcp->mb[2] = LSW(data);
3881 mcp->mb[3] = MSW(data);
3882 mcp->mb[8] = MSW(risc_addr);
3883 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3884 mcp->in_mb = MBX_0;
3885 mcp->tov = 30;
3886 mcp->flags = 0;
3887 rval = qla2x00_mailbox_command(vha, mcp);
3888 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003889 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3890 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003891 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003892 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003893 }
3894
3895 return rval;
3896}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003897
3898int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003899qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3900{
3901 int rval;
3902 uint32_t stat, timer;
3903 uint16_t mb0 = 0;
3904 struct qla_hw_data *ha = vha->hw;
3905 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3906
3907 rval = QLA_SUCCESS;
3908
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003909 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003910
3911 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3912
3913 /* Write the MBC data to the registers */
3914 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3915 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3916 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3917 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3918 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3919
3920 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3921
3922 /* Poll for MBC interrupt */
3923 for (timer = 6000000; timer; timer--) {
3924 /* Check for pending interrupts. */
3925 stat = RD_REG_DWORD(&reg->host_status);
3926 if (stat & HSRX_RISC_INT) {
3927 stat &= 0xff;
3928
3929 if (stat == 0x1 || stat == 0x2 ||
3930 stat == 0x10 || stat == 0x11) {
3931 set_bit(MBX_INTERRUPT,
3932 &ha->mbx_cmd_flags);
3933 mb0 = RD_REG_WORD(&reg->mailbox0);
3934 WRT_REG_DWORD(&reg->hccr,
3935 HCCRX_CLR_RISC_INT);
3936 RD_REG_DWORD(&reg->hccr);
3937 break;
3938 }
3939 }
3940 udelay(5);
3941 }
3942
3943 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
3944 rval = mb0 & MBS_MASK;
3945 else
3946 rval = QLA_FUNCTION_FAILED;
3947
3948 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003949 ql_dbg(ql_dbg_mbx, vha, 0x1104,
3950 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003951 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003952 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003953 }
3954
3955 return rval;
3956}
3957int
Michael Hernandez3064ff32009-12-15 21:29:44 -08003958qla2x00_get_data_rate(scsi_qla_host_t *vha)
3959{
3960 int rval;
3961 mbx_cmd_t mc;
3962 mbx_cmd_t *mcp = &mc;
3963 struct qla_hw_data *ha = vha->hw;
3964
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003965 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
3966
Michael Hernandez3064ff32009-12-15 21:29:44 -08003967 if (!IS_FWI2_CAPABLE(ha))
3968 return QLA_FUNCTION_FAILED;
3969
Michael Hernandez3064ff32009-12-15 21:29:44 -08003970 mcp->mb[0] = MBC_DATA_RATE;
3971 mcp->mb[1] = 0;
3972 mcp->out_mb = MBX_1|MBX_0;
3973 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3974 mcp->tov = MBX_TOV_SECONDS;
3975 mcp->flags = 0;
3976 rval = qla2x00_mailbox_command(vha, mcp);
3977 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003978 ql_dbg(ql_dbg_mbx, vha, 0x1107,
3979 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08003980 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003981 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08003982 if (mcp->mb[1] != 0x7)
3983 ha->link_data_rate = mcp->mb[1];
3984 }
3985
3986 return rval;
3987}
Sarang Radke09ff7012010-03-19 17:03:59 -07003988
3989int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07003990qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
3991{
3992 int rval;
3993 mbx_cmd_t mc;
3994 mbx_cmd_t *mcp = &mc;
3995 struct qla_hw_data *ha = vha->hw;
3996
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003997 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07003998
3999 if (!IS_QLA81XX(ha))
4000 return QLA_FUNCTION_FAILED;
4001 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4002 mcp->out_mb = MBX_0;
4003 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4004 mcp->tov = MBX_TOV_SECONDS;
4005 mcp->flags = 0;
4006
4007 rval = qla2x00_mailbox_command(vha, mcp);
4008
4009 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004010 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4011 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004012 } else {
4013 /* Copy all bits to preserve original value */
4014 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4015
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004016 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004017 }
4018 return rval;
4019}
4020
4021int
4022qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4023{
4024 int rval;
4025 mbx_cmd_t mc;
4026 mbx_cmd_t *mcp = &mc;
4027
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004028 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004029
4030 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4031 /* Copy all bits to preserve original setting */
4032 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4033 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4034 mcp->in_mb = MBX_0;
4035 mcp->tov = MBX_TOV_SECONDS;
4036 mcp->flags = 0;
4037 rval = qla2x00_mailbox_command(vha, mcp);
4038
4039 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004040 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4041 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004042 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004043 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004044
4045 return rval;
4046}
4047
4048
4049int
Sarang Radke09ff7012010-03-19 17:03:59 -07004050qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4051 uint16_t *mb)
4052{
4053 int rval;
4054 mbx_cmd_t mc;
4055 mbx_cmd_t *mcp = &mc;
4056 struct qla_hw_data *ha = vha->hw;
4057
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004058 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4059
Sarang Radke09ff7012010-03-19 17:03:59 -07004060 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4061 return QLA_FUNCTION_FAILED;
4062
Sarang Radke09ff7012010-03-19 17:03:59 -07004063 mcp->mb[0] = MBC_PORT_PARAMS;
4064 mcp->mb[1] = loop_id;
4065 if (ha->flags.fcp_prio_enabled)
4066 mcp->mb[2] = BIT_1;
4067 else
4068 mcp->mb[2] = BIT_2;
4069 mcp->mb[4] = priority & 0xf;
4070 mcp->mb[9] = vha->vp_idx;
4071 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4072 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4073 mcp->tov = 30;
4074 mcp->flags = 0;
4075 rval = qla2x00_mailbox_command(vha, mcp);
4076 if (mb != NULL) {
4077 mb[0] = mcp->mb[0];
4078 mb[1] = mcp->mb[1];
4079 mb[3] = mcp->mb[3];
4080 mb[4] = mcp->mb[4];
4081 }
4082
4083 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004084 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004085 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004086 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004087 }
4088
4089 return rval;
4090}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004091
4092int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004093qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4094{
4095 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004096 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004097 struct qla_hw_data *ha = vha->hw;
4098
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004099 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004100
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004101 /* Integer part */
4102 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004103 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004104 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004105 ha->flags.thermal_supported = 0;
4106 goto fail;
4107 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004108 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004109
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004110 /* Fraction part */
4111 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004112 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004113 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004114 ha->flags.thermal_supported = 0;
4115 goto fail;
4116 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004117 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004118
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004119 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004120fail:
4121 return rval;
4122}
4123
4124int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004125qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4126{
4127 int rval;
4128 struct qla_hw_data *ha = vha->hw;
4129 mbx_cmd_t mc;
4130 mbx_cmd_t *mcp = &mc;
4131
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004132 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4133
Giridhar Malavalia9083012010-04-12 17:59:55 -07004134 if (!IS_FWI2_CAPABLE(ha))
4135 return QLA_FUNCTION_FAILED;
4136
Giridhar Malavalia9083012010-04-12 17:59:55 -07004137 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004138 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004139 mcp->mb[1] = 1;
4140
4141 mcp->out_mb = MBX_1|MBX_0;
4142 mcp->in_mb = MBX_0;
4143 mcp->tov = 30;
4144 mcp->flags = 0;
4145
4146 rval = qla2x00_mailbox_command(vha, mcp);
4147 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004148 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4149 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004150 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004151 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004152 }
4153
4154 return rval;
4155}
4156
4157int
4158qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4159{
4160 int rval;
4161 struct qla_hw_data *ha = vha->hw;
4162 mbx_cmd_t mc;
4163 mbx_cmd_t *mcp = &mc;
4164
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004165 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4166
Giridhar Malavalia9083012010-04-12 17:59:55 -07004167 if (!IS_QLA82XX(ha))
4168 return QLA_FUNCTION_FAILED;
4169
Giridhar Malavalia9083012010-04-12 17:59:55 -07004170 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004171 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004172 mcp->mb[1] = 0;
4173
4174 mcp->out_mb = MBX_1|MBX_0;
4175 mcp->in_mb = MBX_0;
4176 mcp->tov = 30;
4177 mcp->flags = 0;
4178
4179 rval = qla2x00_mailbox_command(vha, mcp);
4180 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004181 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4182 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004183 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004184 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004185 }
4186
4187 return rval;
4188}