blob: be520a9d0b71726e06e2a03a0efec8373221864b [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Andrew Vasquez07e264b2011-03-30 11:46:23 -07003 * Copyright (c) 2003-2011 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090010#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
13/*
14 * qla2x00_mailbox_command
15 * Issue mailbox command and waits for completion.
16 *
17 * Input:
18 * ha = adapter block pointer.
19 * mcp = driver internal mbx struct pointer.
20 *
21 * Output:
22 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
23 *
24 * Returns:
25 * 0 : QLA_SUCCESS = cmd performed success
26 * 1 : QLA_FUNCTION_FAILED (error encountered)
27 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
28 *
29 * Context:
30 * Kernel context.
31 */
32static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080033qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070034{
35 int rval;
36 unsigned long flags = 0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070037 device_reg_t __iomem *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070038 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070039 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -070040 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 uint16_t *iptr;
42 uint16_t __iomem *optr;
43 uint32_t cnt;
44 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080046 struct qla_hw_data *ha = vha->hw;
47 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070048
Saurav Kashyap7c3df132011-07-14 12:00:13 -070049 ql_dbg(ql_dbg_mbx, base_vha, 0x1000, "Entered %s.\n", __func__);
50
51 if (ha->pdev->error_state > pci_channel_io_frozen) {
52 ql_log(ql_log_warn, base_vha, 0x1001,
53 "error_state is greater than pci_channel_io_frozen, "
54 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070055 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070056 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070057
Giridhar Malavalia9083012010-04-12 17:59:55 -070058 if (vha->device_flags & DFLG_DEV_FAILED) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070059 ql_log(ql_log_warn, base_vha, 0x1002,
60 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070061 return QLA_FUNCTION_TIMEOUT;
62 }
63
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070064 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080065 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070070
Andrew Vasquez85880802009-12-15 21:29:46 -080071 if (ha->flags.pci_channel_io_perm_failure) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070072 ql_log(ql_log_warn, base_vha, 0x1003,
73 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080074 return QLA_FUNCTION_TIMEOUT;
75 }
76
Giridhar Malavali862cd012011-02-23 15:27:11 -080077 if (ha->flags.isp82xx_fw_hung) {
78 /* Setting Link-Down error */
79 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070080 ql_log(ql_log_warn, base_vha, 0x1004,
81 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080082 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080083 }
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070086 * Wait for active mailbox commands to finish by waiting at most tov
87 * seconds. This is to serialize actual issuing of mailbox cmds during
88 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080090 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
91 /* Timeout occurred. Return error. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -070092 ql_log(ql_log_warn, base_vha, 0x1005,
93 "Cmd access timeout, Exiting.\n");
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080094 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 }
96
97 ha->flags.mbox_busy = 1;
98 /* Save mailbox command for debug */
99 ha->mcp = mcp;
100
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700101 ql_dbg(ql_dbg_mbx, base_vha, 0x1006,
102 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104 spin_lock_irqsave(&ha->hardware_lock, flags);
105
106 /* Load mailbox registers. */
Giridhar Malavalia9083012010-04-12 17:59:55 -0700107 if (IS_QLA82XX(ha))
108 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
109 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700110 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
111 else
112 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114 iptr = mcp->mb;
115 command = mcp->mb[0];
116 mboxes = mcp->out_mb;
117
118 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
119 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700120 optr =
121 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 if (mboxes & BIT_0)
123 WRT_REG_WORD(optr, *iptr);
124
125 mboxes >>= 1;
126 optr++;
127 iptr++;
128 }
129
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700130 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1111,
131 "Loaded MBX registers (displayed in bytes) =.\n");
132 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1112,
133 (uint8_t *)mcp->mb, 16);
134 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1113,
135 ".\n");
136 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1114,
137 ((uint8_t *)mcp->mb + 0x10), 16);
138 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1115,
139 ".\n");
140 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1116,
141 ((uint8_t *)mcp->mb + 0x20), 8);
142 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1117,
143 "I/O Address = %p.\n", optr);
144 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x100e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 /* Issue set host interrupt command to send cmd out. */
147 ha->flags.mbox_int = 0;
148 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
149
150 /* Unlock mbx registers and wait for interrupt */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700151 ql_dbg(ql_dbg_mbx, base_vha, 0x100f,
152 "Going to unlock irq & waiting for interrupts. "
153 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154
155 /* Wait for mbx cmd completion until timeout */
156
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800157 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
159
Giridhar Malavalia9083012010-04-12 17:59:55 -0700160 if (IS_QLA82XX(ha)) {
161 if (RD_REG_DWORD(&reg->isp82.hint) &
162 HINT_MBX_INT_PENDING) {
163 spin_unlock_irqrestore(&ha->hardware_lock,
164 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800165 ha->flags.mbox_busy = 0;
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);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800191 ha->flags.mbox_busy = 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700192 ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
193 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700194 rval = QLA_FUNCTION_TIMEOUT;
195 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700196 }
197 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
198 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700199 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
200 else
201 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
205 while (!ha->flags.mbox_int) {
206 if (time_after(jiffies, wait_time))
207 break;
208
209 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800210 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Andrew Vasquez85880802009-12-15 21:29:46 -0800212 if (!ha->flags.mbox_int &&
213 !(IS_QLA2200(ha) &&
214 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800215 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 } /* while */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700217 ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
218 "Waited %d sec.\n",
219 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 }
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 /* Check whether we timed out */
223 if (ha->flags.mbox_int) {
224 uint16_t *iptr2;
225
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700226 ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
227 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 /* Got interrupt. Clear the flag. */
230 ha->flags.mbox_int = 0;
231 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
232
Giridhar Malavali71905752011-02-23 15:27:10 -0800233 if (ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700234 ha->flags.mbox_busy = 0;
235 /* Setting Link-Down error */
236 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
237 ha->mcp = NULL;
238 rval = QLA_FUNCTION_FAILED;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700239 ql_log(ql_log_warn, base_vha, 0x1015,
240 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700241 goto premature_exit;
242 }
243
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400244 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247 /* Load return mailbox registers. */
248 iptr2 = mcp->mb;
249 iptr = (uint16_t *)&ha->mailbox_out[0];
250 mboxes = mcp->in_mb;
251 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
252 if (mboxes & BIT_0)
253 *iptr2 = *iptr;
254
255 mboxes >>= 1;
256 iptr2++;
257 iptr++;
258 }
259 } else {
260
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700261 uint16_t mb0;
262 uint32_t ictrl;
263
Andrew Vasqueze4289242007-07-19 15:05:56 -0700264 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700265 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
266 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
267 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700268 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700269 ictrl = RD_REG_WORD(&reg->isp.ictrl);
270 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700271 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
272 "MBX Command timeout for cmd %x.\n", command);
273 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
274 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
275 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
276 "mb[0] = 0x%x.\n", mb0);
277 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 rval = QLA_FUNCTION_TIMEOUT;
280 }
281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 ha->flags.mbox_busy = 0;
283
284 /* Clean up */
285 ha->mcp = NULL;
286
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800287 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700288 ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
289 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
291 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800292 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 }
294
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700295 if (rval == QLA_FUNCTION_TIMEOUT &&
296 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800297 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
298 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 /* not in dpc. schedule it for dpc to take over. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700300 ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
301 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700302
303 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
304 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
305 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800306 if (IS_QLA82XX(ha)) {
307 ql_dbg(ql_dbg_mbx, vha, 0x112a,
308 "disabling pause transmit on port "
309 "0 & 1.\n");
310 qla82xx_wr_32(ha,
311 QLA82XX_CRB_NIU + 0x98,
312 CRB_NIU_XG_PAUSE_CTL_P0|
313 CRB_NIU_XG_PAUSE_CTL_P1);
314 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700315 ql_log(ql_log_info, base_vha, 0x101c,
316 "Mailbox cmd timeout occured. "
317 "Scheduling ISP abort eeh_busy=0x%x.\n",
318 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700319 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
320 qla2xxx_wake_dpc(vha);
321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 /* call abort directly since we are in the DPC thread */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700324 ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
325 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700327 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
328 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
329 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800330 if (IS_QLA82XX(ha)) {
331 ql_dbg(ql_dbg_mbx, vha, 0x112b,
332 "disabling pause transmit on port "
333 "0 & 1.\n");
334 qla82xx_wr_32(ha,
335 QLA82XX_CRB_NIU + 0x98,
336 CRB_NIU_XG_PAUSE_CTL_P0|
337 CRB_NIU_XG_PAUSE_CTL_P1);
338 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700339 ql_log(ql_log_info, base_vha, 0x101e,
340 "Mailbox cmd timeout occured. "
341 "Scheduling ISP abort.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700342
343 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
344 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800345 /* Allow next mbx cmd to come in. */
346 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700347 if (ha->isp_ops->abort_isp(vha)) {
348 /* Failed. retry later. */
349 set_bit(ISP_ABORT_NEEDED,
350 &vha->dpc_flags);
351 }
352 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700353 ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
354 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800355 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 }
358 }
359
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700360premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800362 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Giridhar Malavalid3360962012-02-09 11:14:10 -0800364mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 if (rval) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700366 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800367 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
368 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700370 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 }
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 return rval;
374}
375
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800377qla2x00_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 -0800378 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379{
380 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800381 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 mbx_cmd_t mc;
383 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700385 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Andrew Vasqueze4289242007-07-19 15:05:56 -0700387 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800388 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
389 mcp->mb[8] = MSW(risc_addr);
390 mcp->out_mb = MBX_8|MBX_0;
391 } else {
392 mcp->mb[0] = MBC_LOAD_RISC_RAM;
393 mcp->out_mb = MBX_0;
394 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 mcp->mb[1] = LSW(risc_addr);
396 mcp->mb[2] = MSW(req_dma);
397 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 mcp->mb[6] = MSW(MSD(req_dma));
399 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800400 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700401 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700402 mcp->mb[4] = MSW(risc_code_size);
403 mcp->mb[5] = LSW(risc_code_size);
404 mcp->out_mb |= MBX_5|MBX_4;
405 } else {
406 mcp->mb[4] = LSW(risc_code_size);
407 mcp->out_mb |= MBX_4;
408 }
409
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700411 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800413 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700416 ql_dbg(ql_dbg_mbx, vha, 0x1023,
417 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700419 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 }
421
422 return rval;
423}
424
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700425#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426/*
427 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700428 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 *
430 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700431 * ha = adapter block pointer.
432 * TARGET_QUEUE_LOCK must be released.
433 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 *
435 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700436 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 *
438 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700439 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 */
441int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800442qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
444 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800445 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 mbx_cmd_t mc;
447 mbx_cmd_t *mcp = &mc;
448
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700449 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450
451 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700452 mcp->out_mb = MBX_0;
453 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700454 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700455 mcp->mb[1] = MSW(risc_addr);
456 mcp->mb[2] = LSW(risc_addr);
457 mcp->mb[3] = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800458 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700459 struct nvram_81xx *nv = ha->nvram;
460 mcp->mb[4] = (nv->enhanced_features &
461 EXTENDED_BB_CREDITS);
462 } else
463 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700464 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 mcp->in_mb |= MBX_1;
466 } else {
467 mcp->mb[1] = LSW(risc_addr);
468 mcp->out_mb |= MBX_1;
469 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
470 mcp->mb[2] = 0;
471 mcp->out_mb |= MBX_2;
472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 }
474
Ravi Anandb93480e2008-04-03 13:13:25 -0700475 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800477 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700479 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700480 ql_dbg(ql_dbg_mbx, vha, 0x1026,
481 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700482 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700483 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700484 ql_dbg(ql_dbg_mbx, vha, 0x1027,
485 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700486 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700487 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700488 }
489 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491 return rval;
492}
493
494/*
495 * qla2x00_get_fw_version
496 * Get firmware version.
497 *
498 * Input:
499 * ha: adapter state pointer.
500 * major: pointer for major number.
501 * minor: pointer for minor number.
502 * subminor: pointer for subminor number.
503 *
504 * Returns:
505 * qla2x00 local function return status code.
506 *
507 * Context:
508 * Kernel context.
509 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700510int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800511qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512{
513 int rval;
514 mbx_cmd_t mc;
515 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800516 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700518 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
521 mcp->out_mb = MBX_0;
522 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800523 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700524 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800525 if (IS_QLA83XX(vha->hw))
526 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700528 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800529 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700530 if (rval != QLA_SUCCESS)
531 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800534 ha->fw_major_version = mcp->mb[1];
535 ha->fw_minor_version = mcp->mb[2];
536 ha->fw_subminor_version = mcp->mb[3];
537 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800538 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800539 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800541 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
542 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
543 ha->mpi_version[0] = mcp->mb[10] & 0xff;
544 ha->mpi_version[1] = mcp->mb[11] >> 8;
545 ha->mpi_version[2] = mcp->mb[11] & 0xff;
546 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
547 ha->phy_version[0] = mcp->mb[8] & 0xff;
548 ha->phy_version[1] = mcp->mb[9] >> 8;
549 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800550 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800551 if (IS_QLA83XX(ha)) {
552 if (mcp->mb[6] & BIT_15) {
553 ha->fw_attributes_h = mcp->mb[15];
554 ha->fw_attributes_ext[0] = mcp->mb[16];
555 ha->fw_attributes_ext[1] = mcp->mb[17];
556 ql_dbg(ql_dbg_mbx, vha, 0x1139,
557 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
558 __func__, mcp->mb[15], mcp->mb[6]);
559 } else
560 ql_dbg(ql_dbg_mbx, vha, 0x112f,
561 "%s: FwAttributes [Upper] invalid, MB6:%04x\n",
562 __func__, mcp->mb[6]);
563 }
564
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700565failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 if (rval != QLA_SUCCESS) {
567 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700568 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 } else {
570 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700571 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700573 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574}
575
576/*
577 * qla2x00_get_fw_options
578 * Set firmware options.
579 *
580 * Input:
581 * ha = adapter block pointer.
582 * fwopt = pointer for firmware options.
583 *
584 * Returns:
585 * qla2x00 local function return status code.
586 *
587 * Context:
588 * Kernel context.
589 */
590int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800591qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
593 int rval;
594 mbx_cmd_t mc;
595 mbx_cmd_t *mcp = &mc;
596
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700597 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
600 mcp->out_mb = MBX_0;
601 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700602 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800604 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
606 if (rval != QLA_SUCCESS) {
607 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700608 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700610 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 fwopts[1] = mcp->mb[1];
612 fwopts[2] = mcp->mb[2];
613 fwopts[3] = mcp->mb[3];
614
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700615 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617
618 return rval;
619}
620
621
622/*
623 * qla2x00_set_fw_options
624 * Set firmware options.
625 *
626 * Input:
627 * ha = adapter block pointer.
628 * fwopt = pointer for firmware options.
629 *
630 * Returns:
631 * qla2x00 local function return status code.
632 *
633 * Context:
634 * Kernel context.
635 */
636int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800637qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638{
639 int rval;
640 mbx_cmd_t mc;
641 mbx_cmd_t *mcp = &mc;
642
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700643 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
646 mcp->mb[1] = fwopts[1];
647 mcp->mb[2] = fwopts[2];
648 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700649 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800651 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700652 mcp->in_mb |= MBX_1;
653 } else {
654 mcp->mb[10] = fwopts[10];
655 mcp->mb[11] = fwopts[11];
656 mcp->mb[12] = 0; /* Undocumented, but used */
657 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
658 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700659 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800661 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700663 fwopts[0] = mcp->mb[0];
664
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (rval != QLA_SUCCESS) {
666 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700667 ql_dbg(ql_dbg_mbx, vha, 0x1030,
668 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 } else {
670 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700671 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 }
673
674 return rval;
675}
676
677/*
678 * qla2x00_mbx_reg_test
679 * Mailbox register wrap test.
680 *
681 * Input:
682 * ha = adapter block pointer.
683 * TARGET_QUEUE_LOCK must be released.
684 * ADAPTER_STATE_LOCK must be released.
685 *
686 * Returns:
687 * qla2x00 local function return status code.
688 *
689 * Context:
690 * Kernel context.
691 */
692int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800693qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694{
695 int rval;
696 mbx_cmd_t mc;
697 mbx_cmd_t *mcp = &mc;
698
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700699 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
702 mcp->mb[1] = 0xAAAA;
703 mcp->mb[2] = 0x5555;
704 mcp->mb[3] = 0xAA55;
705 mcp->mb[4] = 0x55AA;
706 mcp->mb[5] = 0xA5A5;
707 mcp->mb[6] = 0x5A5A;
708 mcp->mb[7] = 0x2525;
709 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
710 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 -0700711 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800713 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
715 if (rval == QLA_SUCCESS) {
716 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
717 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
718 rval = QLA_FUNCTION_FAILED;
719 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
720 mcp->mb[7] != 0x2525)
721 rval = QLA_FUNCTION_FAILED;
722 }
723
724 if (rval != QLA_SUCCESS) {
725 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700726 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 } else {
728 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700729 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 }
731
732 return rval;
733}
734
735/*
736 * qla2x00_verify_checksum
737 * Verify firmware checksum.
738 *
739 * Input:
740 * ha = adapter block pointer.
741 * TARGET_QUEUE_LOCK must be released.
742 * ADAPTER_STATE_LOCK must be released.
743 *
744 * Returns:
745 * qla2x00 local function return status code.
746 *
747 * Context:
748 * Kernel context.
749 */
750int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800751qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752{
753 int rval;
754 mbx_cmd_t mc;
755 mbx_cmd_t *mcp = &mc;
756
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700757 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
759 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700760 mcp->out_mb = MBX_0;
761 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800762 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700763 mcp->mb[1] = MSW(risc_addr);
764 mcp->mb[2] = LSW(risc_addr);
765 mcp->out_mb |= MBX_2|MBX_1;
766 mcp->in_mb |= MBX_2|MBX_1;
767 } else {
768 mcp->mb[1] = LSW(risc_addr);
769 mcp->out_mb |= MBX_1;
770 mcp->in_mb |= MBX_1;
771 }
772
Ravi Anandb93480e2008-04-03 13:13:25 -0700773 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800775 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
777 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700778 ql_dbg(ql_dbg_mbx, vha, 0x1036,
779 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
780 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700782 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 }
784
785 return rval;
786}
787
788/*
789 * qla2x00_issue_iocb
790 * Issue IOCB using mailbox command
791 *
792 * Input:
793 * ha = adapter state pointer.
794 * buffer = buffer pointer.
795 * phys_addr = physical address of buffer.
796 * size = size of buffer.
797 * TARGET_QUEUE_LOCK must be released.
798 * ADAPTER_STATE_LOCK must be released.
799 *
800 * Returns:
801 * qla2x00 local function return status code.
802 *
803 * Context:
804 * Kernel context.
805 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700806int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800807qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700808 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809{
810 int rval;
811 mbx_cmd_t mc;
812 mbx_cmd_t *mcp = &mc;
813
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700814 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
817 mcp->mb[1] = 0;
818 mcp->mb[2] = MSW(phys_addr);
819 mcp->mb[3] = LSW(phys_addr);
820 mcp->mb[6] = MSW(MSD(phys_addr));
821 mcp->mb[7] = LSW(MSD(phys_addr));
822 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
823 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700824 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800826 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 if (rval != QLA_SUCCESS) {
829 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700830 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700832 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
833
834 /* Mask reserved bits. */
835 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800836 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700837 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 }
839
840 return rval;
841}
842
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700843int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800844qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700845 size_t size)
846{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800847 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700848 MBX_TOV_SECONDS);
849}
850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851/*
852 * qla2x00_abort_command
853 * Abort command aborts a specified IOCB.
854 *
855 * Input:
856 * ha = adapter block pointer.
857 * sp = SB structure pointer.
858 *
859 * Returns:
860 * qla2x00 local function return status code.
861 *
862 * Context:
863 * Kernel context.
864 */
865int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700866qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867{
868 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800870 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 mbx_cmd_t mc;
872 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700873 fc_port_t *fcport = sp->fcport;
874 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800875 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700876 struct req_que *req = vha->req;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700878 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700880 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800882 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 break;
884 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700885 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887 if (handle == MAX_OUTSTANDING_COMMANDS) {
888 /* command not found */
889 return QLA_FUNCTION_FAILED;
890 }
891
892 mcp->mb[0] = MBC_ABORT_COMMAND;
893 if (HAS_EXTENDED_IDS(ha))
894 mcp->mb[1] = fcport->loop_id;
895 else
896 mcp->mb[1] = fcport->loop_id << 8;
897 mcp->mb[2] = (uint16_t)handle;
898 mcp->mb[3] = (uint16_t)(handle >> 16);
bdf79622005-04-17 15:06:53 -0500899 mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
901 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700902 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800904 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
906 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700907 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700909 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 }
911
912 return rval;
913}
914
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700916qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700918 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 mbx_cmd_t mc;
920 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800921 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800922 struct req_que *req;
923 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
Andrew Vasquez523ec772008-04-03 13:13:24 -0700925 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800926 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700927
928 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
929
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700930 req = vha->hw->req_q_map[0];
931 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700933 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800934 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 mcp->mb[1] = fcport->loop_id;
936 mcp->mb[10] = 0;
937 mcp->out_mb |= MBX_10;
938 } else {
939 mcp->mb[1] = fcport->loop_id << 8;
940 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800941 mcp->mb[2] = vha->hw->loop_reset_delay;
942 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
944 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700945 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800947 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700949 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700950 }
951
952 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800953 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
954 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700955 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700956 ql_dbg(ql_dbg_mbx, vha, 0x1040,
957 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700959 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700960 }
961
962 return rval;
963}
964
965int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700966qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700967{
968 int rval, rval2;
969 mbx_cmd_t mc;
970 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800971 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800972 struct req_que *req;
973 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700974
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800975 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700976
977 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
978
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700979 req = vha->hw->req_q_map[0];
980 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700981 mcp->mb[0] = MBC_LUN_RESET;
982 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800983 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700984 mcp->mb[1] = fcport->loop_id;
985 else
986 mcp->mb[1] = fcport->loop_id << 8;
987 mcp->mb[2] = l;
988 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800989 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700990
991 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700992 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700993 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800994 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700995 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700996 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700997 }
998
999 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001000 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1001 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001002 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001003 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1004 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001005 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001006 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 }
1008
1009 return rval;
1010}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011
1012/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 * qla2x00_get_adapter_id
1014 * Get adapter ID and topology.
1015 *
1016 * Input:
1017 * ha = adapter block pointer.
1018 * id = pointer for loop ID.
1019 * al_pa = pointer for AL_PA.
1020 * area = pointer for area.
1021 * domain = pointer for domain.
1022 * top = pointer for topology.
1023 * TARGET_QUEUE_LOCK must be released.
1024 * ADAPTER_STATE_LOCK must be released.
1025 *
1026 * Returns:
1027 * qla2x00 local function return status code.
1028 *
1029 * Context:
1030 * Kernel context.
1031 */
1032int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001033qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001034 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035{
1036 int rval;
1037 mbx_cmd_t mc;
1038 mbx_cmd_t *mcp = &mc;
1039
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001040 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
1042 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001043 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001044 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001045 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001046 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001047 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001048 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001050 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001051 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1052 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001053 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1054 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
1056 /* Return data. */
1057 *id = mcp->mb[1];
1058 *al_pa = LSB(mcp->mb[2]);
1059 *area = MSB(mcp->mb[2]);
1060 *domain = LSB(mcp->mb[3]);
1061 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001062 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
1064 if (rval != QLA_SUCCESS) {
1065 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001066 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001068 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001069
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001070 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001071 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1072 vha->fcoe_fcf_idx = mcp->mb[10];
1073 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1074 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1075 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1076 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1077 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1078 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1079 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 }
1081
1082 return rval;
1083}
1084
1085/*
1086 * qla2x00_get_retry_cnt
1087 * Get current firmware login retry count and delay.
1088 *
1089 * Input:
1090 * ha = adapter block pointer.
1091 * retry_cnt = pointer to login retry count.
1092 * tov = pointer to login timeout value.
1093 *
1094 * Returns:
1095 * qla2x00 local function return status code.
1096 *
1097 * Context:
1098 * Kernel context.
1099 */
1100int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001101qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 uint16_t *r_a_tov)
1103{
1104 int rval;
1105 uint16_t ratov;
1106 mbx_cmd_t mc;
1107 mbx_cmd_t *mcp = &mc;
1108
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001109 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
1111 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1112 mcp->out_mb = MBX_0;
1113 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001114 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001116 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118 if (rval != QLA_SUCCESS) {
1119 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001120 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1121 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 } else {
1123 /* Convert returned data and check our values. */
1124 *r_a_tov = mcp->mb[3] / 2;
1125 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1126 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1127 /* Update to the larger values */
1128 *retry_cnt = (uint8_t)mcp->mb[1];
1129 *tov = ratov;
1130 }
1131
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001132 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1133 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 }
1135
1136 return rval;
1137}
1138
1139/*
1140 * qla2x00_init_firmware
1141 * Initialize adapter firmware.
1142 *
1143 * Input:
1144 * ha = adapter block pointer.
1145 * dptr = Initialization control block pointer.
1146 * size = size of initialization control block.
1147 * TARGET_QUEUE_LOCK must be released.
1148 * ADAPTER_STATE_LOCK must be released.
1149 *
1150 * Returns:
1151 * qla2x00 local function return status code.
1152 *
1153 * Context:
1154 * Kernel context.
1155 */
1156int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001157qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158{
1159 int rval;
1160 mbx_cmd_t mc;
1161 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001162 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001164 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165
Giridhar Malavalia9083012010-04-12 17:59:55 -07001166 if (IS_QLA82XX(ha) && ql2xdbwr)
1167 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1168 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1169
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001170 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001171 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1172 else
1173 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1174
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001175 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 mcp->mb[2] = MSW(ha->init_cb_dma);
1177 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1179 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001180 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001181 if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001182 mcp->mb[1] = BIT_0;
1183 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1184 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1185 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1186 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1187 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1188 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1189 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001190 /* 1 and 2 should normally be captured. */
1191 mcp->in_mb = MBX_2|MBX_1|MBX_0;
1192 if (IS_QLA83XX(ha))
1193 /* mb3 is additional info about the installed SFP. */
1194 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 mcp->buf_size = size;
1196 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001197 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001198 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
1200 if (rval != QLA_SUCCESS) {
1201 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001202 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001203 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1204 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 } else {
1206 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001207 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
1209
1210 return rval;
1211}
1212
1213/*
1214 * qla2x00_get_port_database
1215 * Issue normal/enhanced get port database mailbox command
1216 * and copy device name as necessary.
1217 *
1218 * Input:
1219 * ha = adapter state pointer.
1220 * dev = structure pointer.
1221 * opt = enhanced cmd option byte.
1222 *
1223 * Returns:
1224 * qla2x00 local function return status code.
1225 *
1226 * Context:
1227 * Kernel context.
1228 */
1229int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001230qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231{
1232 int rval;
1233 mbx_cmd_t mc;
1234 mbx_cmd_t *mcp = &mc;
1235 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001236 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001238 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001240 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001242 pd24 = NULL;
1243 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001245 ql_log(ql_log_warn, vha, 0x1050,
1246 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 return QLA_MEMORY_ALLOC_FAILED;
1248 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001249 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001251 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001252 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 mcp->mb[2] = MSW(pd_dma);
1255 mcp->mb[3] = LSW(pd_dma);
1256 mcp->mb[6] = MSW(MSD(pd_dma));
1257 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001258 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001259 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001261 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001262 mcp->mb[1] = fcport->loop_id;
1263 mcp->mb[10] = opt;
1264 mcp->out_mb |= MBX_10|MBX_1;
1265 mcp->in_mb |= MBX_1;
1266 } else if (HAS_EXTENDED_IDS(ha)) {
1267 mcp->mb[1] = fcport->loop_id;
1268 mcp->mb[10] = opt;
1269 mcp->out_mb |= MBX_10|MBX_1;
1270 } else {
1271 mcp->mb[1] = fcport->loop_id << 8 | opt;
1272 mcp->out_mb |= MBX_1;
1273 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001274 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1275 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 mcp->flags = MBX_DMA_IN;
1277 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001278 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 if (rval != QLA_SUCCESS)
1280 goto gpd_error_out;
1281
Andrew Vasqueze4289242007-07-19 15:05:56 -07001282 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001283 pd24 = (struct port_database_24xx *) pd;
1284
1285 /* Check for logged in state. */
1286 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1287 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001288 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1289 "Unable to verify login-state (%x/%x) for "
1290 "loop_id %x.\n", pd24->current_login_state,
1291 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001292 rval = QLA_FUNCTION_FAILED;
1293 goto gpd_error_out;
1294 }
1295
1296 /* Names are little-endian. */
1297 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1298 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1299
1300 /* Get port_id of device. */
1301 fcport->d_id.b.domain = pd24->port_id[0];
1302 fcport->d_id.b.area = pd24->port_id[1];
1303 fcport->d_id.b.al_pa = pd24->port_id[2];
1304 fcport->d_id.b.rsvd_1 = 0;
1305
1306 /* If not target must be initiator or unknown type. */
1307 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1308 fcport->port_type = FCT_INITIATOR;
1309 else
1310 fcport->port_type = FCT_TARGET;
1311 } else {
1312 /* Check for logged in state. */
1313 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1314 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001315 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1316 "Unable to verify login-state (%x/%x) - "
1317 "portid=%02x%02x%02x.\n", pd->master_state,
1318 pd->slave_state, fcport->d_id.b.domain,
1319 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001320 rval = QLA_FUNCTION_FAILED;
1321 goto gpd_error_out;
1322 }
1323
1324 /* Names are little-endian. */
1325 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1326 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1327
1328 /* Get port_id of device. */
1329 fcport->d_id.b.domain = pd->port_id[0];
1330 fcport->d_id.b.area = pd->port_id[3];
1331 fcport->d_id.b.al_pa = pd->port_id[2];
1332 fcport->d_id.b.rsvd_1 = 0;
1333
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001334 /* If not target must be initiator or unknown type. */
1335 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1336 fcport->port_type = FCT_INITIATOR;
1337 else
1338 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001339
1340 /* Passback COS information. */
1341 fcport->supported_classes = (pd->options & BIT_4) ?
1342 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 }
1344
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345gpd_error_out:
1346 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1347
1348 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001349 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1350 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1351 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001353 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 }
1355
1356 return rval;
1357}
1358
1359/*
1360 * qla2x00_get_firmware_state
1361 * Get adapter firmware state.
1362 *
1363 * Input:
1364 * ha = adapter block pointer.
1365 * dptr = pointer for firmware state.
1366 * TARGET_QUEUE_LOCK must be released.
1367 * ADAPTER_STATE_LOCK must be released.
1368 *
1369 * Returns:
1370 * qla2x00 local function return status code.
1371 *
1372 * Context:
1373 * Kernel context.
1374 */
1375int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001376qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377{
1378 int rval;
1379 mbx_cmd_t mc;
1380 mbx_cmd_t *mcp = &mc;
1381
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001382 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1385 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001386 if (IS_FWI2_CAPABLE(vha->hw))
1387 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1388 else
1389 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001390 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001392 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001394 /* Return firmware states. */
1395 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001396 if (IS_FWI2_CAPABLE(vha->hw)) {
1397 states[1] = mcp->mb[2];
1398 states[2] = mcp->mb[3];
1399 states[3] = mcp->mb[4];
1400 states[4] = mcp->mb[5];
1401 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
1403 if (rval != QLA_SUCCESS) {
1404 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001405 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 } else {
1407 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001408 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 }
1410
1411 return rval;
1412}
1413
1414/*
1415 * qla2x00_get_port_name
1416 * Issue get port name mailbox command.
1417 * Returned name is in big endian format.
1418 *
1419 * Input:
1420 * ha = adapter block pointer.
1421 * loop_id = loop ID of device.
1422 * name = pointer for name.
1423 * TARGET_QUEUE_LOCK must be released.
1424 * ADAPTER_STATE_LOCK must be released.
1425 *
1426 * Returns:
1427 * qla2x00 local function return status code.
1428 *
1429 * Context:
1430 * Kernel context.
1431 */
1432int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001433qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 uint8_t opt)
1435{
1436 int rval;
1437 mbx_cmd_t mc;
1438 mbx_cmd_t *mcp = &mc;
1439
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001440 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001443 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001444 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001445 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 mcp->mb[1] = loop_id;
1447 mcp->mb[10] = opt;
1448 mcp->out_mb |= MBX_10;
1449 } else {
1450 mcp->mb[1] = loop_id << 8 | opt;
1451 }
1452
1453 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001454 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001456 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
1458 if (rval != QLA_SUCCESS) {
1459 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001460 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 } else {
1462 if (name != NULL) {
1463 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001464 name[0] = MSB(mcp->mb[2]);
1465 name[1] = LSB(mcp->mb[2]);
1466 name[2] = MSB(mcp->mb[3]);
1467 name[3] = LSB(mcp->mb[3]);
1468 name[4] = MSB(mcp->mb[6]);
1469 name[5] = LSB(mcp->mb[6]);
1470 name[6] = MSB(mcp->mb[7]);
1471 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 }
1473
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001474 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 }
1476
1477 return rval;
1478}
1479
1480/*
1481 * qla2x00_lip_reset
1482 * Issue LIP reset mailbox command.
1483 *
1484 * Input:
1485 * ha = adapter block pointer.
1486 * TARGET_QUEUE_LOCK must be released.
1487 * ADAPTER_STATE_LOCK must be released.
1488 *
1489 * Returns:
1490 * qla2x00 local function return status code.
1491 *
1492 * Context:
1493 * Kernel context.
1494 */
1495int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001496qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497{
1498 int rval;
1499 mbx_cmd_t mc;
1500 mbx_cmd_t *mcp = &mc;
1501
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001502 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001504 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001505 /* Logout across all FCFs. */
1506 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1507 mcp->mb[1] = BIT_1;
1508 mcp->mb[2] = 0;
1509 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1510 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001511 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001512 mcp->mb[1] = BIT_6;
1513 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001514 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001515 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001517 mcp->mb[0] = MBC_LIP_RESET;
1518 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001519 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001520 mcp->mb[1] = 0x00ff;
1521 mcp->mb[10] = 0;
1522 mcp->out_mb |= MBX_10;
1523 } else {
1524 mcp->mb[1] = 0xff00;
1525 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001526 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001527 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001530 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001532 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
1534 if (rval != QLA_SUCCESS) {
1535 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001536 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 } else {
1538 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001539 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 }
1541
1542 return rval;
1543}
1544
1545/*
1546 * qla2x00_send_sns
1547 * Send SNS command.
1548 *
1549 * Input:
1550 * ha = adapter block pointer.
1551 * sns = pointer for command.
1552 * cmd_size = command size.
1553 * buf_size = response/command size.
1554 * TARGET_QUEUE_LOCK must be released.
1555 * ADAPTER_STATE_LOCK must be released.
1556 *
1557 * Returns:
1558 * qla2x00 local function return status code.
1559 *
1560 * Context:
1561 * Kernel context.
1562 */
1563int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001564qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 uint16_t cmd_size, size_t buf_size)
1566{
1567 int rval;
1568 mbx_cmd_t mc;
1569 mbx_cmd_t *mcp = &mc;
1570
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001571 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001573 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1574 "Retry cnt=%d ratov=%d total tov=%d.\n",
1575 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
1577 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1578 mcp->mb[1] = cmd_size;
1579 mcp->mb[2] = MSW(sns_phys_address);
1580 mcp->mb[3] = LSW(sns_phys_address);
1581 mcp->mb[6] = MSW(MSD(sns_phys_address));
1582 mcp->mb[7] = LSW(MSD(sns_phys_address));
1583 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1584 mcp->in_mb = MBX_0|MBX_1;
1585 mcp->buf_size = buf_size;
1586 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001587 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1588 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 if (rval != QLA_SUCCESS) {
1591 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001592 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1593 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1594 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 } else {
1596 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001597 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 }
1599
1600 return rval;
1601}
1602
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001603int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001604qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001605 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1606{
1607 int rval;
1608
1609 struct logio_entry_24xx *lg;
1610 dma_addr_t lg_dma;
1611 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001612 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001613 struct req_que *req;
1614 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001615
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001616 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001617
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001618 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001619 req = ha->req_q_map[0];
1620 else
1621 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001622 rsp = req->rsp;
1623
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001624 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1625 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001626 ql_log(ql_log_warn, vha, 0x1062,
1627 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001628 return QLA_MEMORY_ALLOC_FAILED;
1629 }
1630 memset(lg, 0, sizeof(struct logio_entry_24xx));
1631
1632 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1633 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001634 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001635 lg->nport_handle = cpu_to_le16(loop_id);
1636 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1637 if (opt & BIT_0)
1638 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001639 if (opt & BIT_1)
1640 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001641 lg->port_id[0] = al_pa;
1642 lg->port_id[1] = area;
1643 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001644 lg->vp_index = vha->vp_idx;
1645 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001646 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001647 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1648 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001649 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001650 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1651 "Failed to complete IOCB -- error status (%x).\n",
1652 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001653 rval = QLA_FUNCTION_FAILED;
1654 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1655 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1656 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1657
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001658 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1659 "Failed to complete IOCB -- completion status (%x) "
1660 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1661 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001662
1663 switch (iop[0]) {
1664 case LSC_SCODE_PORTID_USED:
1665 mb[0] = MBS_PORT_ID_USED;
1666 mb[1] = LSW(iop[1]);
1667 break;
1668 case LSC_SCODE_NPORT_USED:
1669 mb[0] = MBS_LOOP_ID_USED;
1670 break;
1671 case LSC_SCODE_NOLINK:
1672 case LSC_SCODE_NOIOCB:
1673 case LSC_SCODE_NOXCB:
1674 case LSC_SCODE_CMD_FAILED:
1675 case LSC_SCODE_NOFABRIC:
1676 case LSC_SCODE_FW_NOT_READY:
1677 case LSC_SCODE_NOT_LOGGED_IN:
1678 case LSC_SCODE_NOPCB:
1679 case LSC_SCODE_ELS_REJECT:
1680 case LSC_SCODE_CMD_PARAM_ERR:
1681 case LSC_SCODE_NONPORT:
1682 case LSC_SCODE_LOGGED_IN:
1683 case LSC_SCODE_NOFLOGI_ACC:
1684 default:
1685 mb[0] = MBS_COMMAND_ERROR;
1686 break;
1687 }
1688 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001689 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001690
1691 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1692
1693 mb[0] = MBS_COMMAND_COMPLETE;
1694 mb[1] = 0;
1695 if (iop[0] & BIT_4) {
1696 if (iop[0] & BIT_8)
1697 mb[1] |= BIT_1;
1698 } else
1699 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001700
1701 /* Passback COS information. */
1702 mb[10] = 0;
1703 if (lg->io_parameter[7] || lg->io_parameter[8])
1704 mb[10] |= BIT_0; /* Class 2. */
1705 if (lg->io_parameter[9] || lg->io_parameter[10])
1706 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001707 }
1708
1709 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1710
1711 return rval;
1712}
1713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714/*
1715 * qla2x00_login_fabric
1716 * Issue login fabric port mailbox command.
1717 *
1718 * Input:
1719 * ha = adapter block pointer.
1720 * loop_id = device loop ID.
1721 * domain = device domain.
1722 * area = device area.
1723 * al_pa = device AL_PA.
1724 * status = pointer for return status.
1725 * opt = command options.
1726 * TARGET_QUEUE_LOCK must be released.
1727 * ADAPTER_STATE_LOCK must be released.
1728 *
1729 * Returns:
1730 * qla2x00 local function return status code.
1731 *
1732 * Context:
1733 * Kernel context.
1734 */
1735int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001736qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1738{
1739 int rval;
1740 mbx_cmd_t mc;
1741 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001742 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001744 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
1746 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1747 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1748 if (HAS_EXTENDED_IDS(ha)) {
1749 mcp->mb[1] = loop_id;
1750 mcp->mb[10] = opt;
1751 mcp->out_mb |= MBX_10;
1752 } else {
1753 mcp->mb[1] = (loop_id << 8) | opt;
1754 }
1755 mcp->mb[2] = domain;
1756 mcp->mb[3] = area << 8 | al_pa;
1757
1758 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1759 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1760 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001761 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
1763 /* Return mailbox statuses. */
1764 if (mb != NULL) {
1765 mb[0] = mcp->mb[0];
1766 mb[1] = mcp->mb[1];
1767 mb[2] = mcp->mb[2];
1768 mb[6] = mcp->mb[6];
1769 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001770 /* COS retrieved from Get-Port-Database mailbox command. */
1771 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 }
1773
1774 if (rval != QLA_SUCCESS) {
1775 /* RLU tmp code: need to change main mailbox_command function to
1776 * return ok even when the mailbox completion value is not
1777 * SUCCESS. The caller needs to be responsible to interpret
1778 * the return values of this mailbox command if we're not
1779 * to change too much of the existing code.
1780 */
1781 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1782 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1783 mcp->mb[0] == 0x4006)
1784 rval = QLA_SUCCESS;
1785
1786 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001787 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1788 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1789 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 } else {
1791 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001792 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 }
1794
1795 return rval;
1796}
1797
1798/*
1799 * qla2x00_login_local_device
1800 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001801 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 * Input:
1803 * ha = adapter block pointer.
1804 * loop_id = device loop ID.
1805 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001806 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 * Returns:
1808 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001809 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 * Context:
1811 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001812 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 */
1814int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001815qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 uint16_t *mb_ret, uint8_t opt)
1817{
1818 int rval;
1819 mbx_cmd_t mc;
1820 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001821 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001823 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1824
Andrew Vasqueze4289242007-07-19 15:05:56 -07001825 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001826 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001827 fcport->d_id.b.domain, fcport->d_id.b.area,
1828 fcport->d_id.b.al_pa, mb_ret, opt);
1829
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1831 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001832 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001834 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 mcp->mb[2] = opt;
1836 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1837 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1838 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1839 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001840 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841
1842 /* Return mailbox statuses. */
1843 if (mb_ret != NULL) {
1844 mb_ret[0] = mcp->mb[0];
1845 mb_ret[1] = mcp->mb[1];
1846 mb_ret[6] = mcp->mb[6];
1847 mb_ret[7] = mcp->mb[7];
1848 }
1849
1850 if (rval != QLA_SUCCESS) {
1851 /* AV tmp code: need to change main mailbox_command function to
1852 * return ok even when the mailbox completion value is not
1853 * SUCCESS. The caller needs to be responsible to interpret
1854 * the return values of this mailbox command if we're not
1855 * to change too much of the existing code.
1856 */
1857 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1858 rval = QLA_SUCCESS;
1859
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001860 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1861 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1862 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 } else {
1864 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001865 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 }
1867
1868 return (rval);
1869}
1870
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001871int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001872qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001873 uint8_t area, uint8_t al_pa)
1874{
1875 int rval;
1876 struct logio_entry_24xx *lg;
1877 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001878 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001879 struct req_que *req;
1880 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001881
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001882 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001883
1884 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1885 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001886 ql_log(ql_log_warn, vha, 0x106e,
1887 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001888 return QLA_MEMORY_ALLOC_FAILED;
1889 }
1890 memset(lg, 0, sizeof(struct logio_entry_24xx));
1891
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001892 if (ql2xmaxqueues > 1)
1893 req = ha->req_q_map[0];
1894 else
1895 req = vha->req;
1896 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001897 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1898 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001899 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001900 lg->nport_handle = cpu_to_le16(loop_id);
1901 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001902 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1903 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001904 lg->port_id[0] = al_pa;
1905 lg->port_id[1] = area;
1906 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001907 lg->vp_index = vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001908
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001909 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001910 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001911 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1912 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001913 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001914 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1915 "Failed to complete IOCB -- error status (%x).\n",
1916 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001917 rval = QLA_FUNCTION_FAILED;
1918 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001919 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1920 "Failed to complete IOCB -- completion status (%x) "
1921 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001922 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001923 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001924 } else {
1925 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001926 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001927 }
1928
1929 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1930
1931 return rval;
1932}
1933
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934/*
1935 * qla2x00_fabric_logout
1936 * Issue logout fabric port mailbox command.
1937 *
1938 * Input:
1939 * ha = adapter block pointer.
1940 * loop_id = device loop ID.
1941 * TARGET_QUEUE_LOCK must be released.
1942 * ADAPTER_STATE_LOCK must be released.
1943 *
1944 * Returns:
1945 * qla2x00 local function return status code.
1946 *
1947 * Context:
1948 * Kernel context.
1949 */
1950int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001951qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001952 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001953{
1954 int rval;
1955 mbx_cmd_t mc;
1956 mbx_cmd_t *mcp = &mc;
1957
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001958 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
1960 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1961 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001962 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963 mcp->mb[1] = loop_id;
1964 mcp->mb[10] = 0;
1965 mcp->out_mb |= MBX_10;
1966 } else {
1967 mcp->mb[1] = loop_id << 8;
1968 }
1969
1970 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001971 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001973 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
1975 if (rval != QLA_SUCCESS) {
1976 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001977 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1978 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979 } else {
1980 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001981 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 }
1983
1984 return rval;
1985}
1986
1987/*
1988 * qla2x00_full_login_lip
1989 * Issue full login LIP mailbox command.
1990 *
1991 * Input:
1992 * ha = adapter block pointer.
1993 * TARGET_QUEUE_LOCK must be released.
1994 * ADAPTER_STATE_LOCK must be released.
1995 *
1996 * Returns:
1997 * qla2x00 local function return status code.
1998 *
1999 * Context:
2000 * Kernel context.
2001 */
2002int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002003qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004{
2005 int rval;
2006 mbx_cmd_t mc;
2007 mbx_cmd_t *mcp = &mc;
2008
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002009 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002012 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002013 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 mcp->mb[3] = 0;
2015 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2016 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002017 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002019 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
2021 if (rval != QLA_SUCCESS) {
2022 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002023 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 } else {
2025 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002026 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 }
2028
2029 return rval;
2030}
2031
2032/*
2033 * qla2x00_get_id_list
2034 *
2035 * Input:
2036 * ha = adapter block pointer.
2037 *
2038 * Returns:
2039 * qla2x00 local function return status code.
2040 *
2041 * Context:
2042 * Kernel context.
2043 */
2044int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002045qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 uint16_t *entries)
2047{
2048 int rval;
2049 mbx_cmd_t mc;
2050 mbx_cmd_t *mcp = &mc;
2051
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002052 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 if (id_list == NULL)
2055 return QLA_FUNCTION_FAILED;
2056
2057 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002058 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002059 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002060 mcp->mb[2] = MSW(id_list_dma);
2061 mcp->mb[3] = LSW(id_list_dma);
2062 mcp->mb[6] = MSW(MSD(id_list_dma));
2063 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002064 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002065 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002066 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002067 } else {
2068 mcp->mb[1] = MSW(id_list_dma);
2069 mcp->mb[2] = LSW(id_list_dma);
2070 mcp->mb[3] = MSW(MSD(id_list_dma));
2071 mcp->mb[6] = LSW(MSD(id_list_dma));
2072 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2073 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002075 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002077 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
2079 if (rval != QLA_SUCCESS) {
2080 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002081 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 } else {
2083 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002084 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 }
2086
2087 return rval;
2088}
2089
2090/*
2091 * qla2x00_get_resource_cnts
2092 * Get current firmware resource counts.
2093 *
2094 * Input:
2095 * ha = adapter block pointer.
2096 *
2097 * Returns:
2098 * qla2x00 local function return status code.
2099 *
2100 * Context:
2101 * Kernel context.
2102 */
2103int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002104qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002105 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002106 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107{
2108 int rval;
2109 mbx_cmd_t mc;
2110 mbx_cmd_t *mcp = &mc;
2111
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002112 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
2114 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2115 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002116 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002117 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002118 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002119 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002121 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122
2123 if (rval != QLA_SUCCESS) {
2124 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002125 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2126 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002128 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2129 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2130 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2131 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2132 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133
2134 if (cur_xchg_cnt)
2135 *cur_xchg_cnt = mcp->mb[3];
2136 if (orig_xchg_cnt)
2137 *orig_xchg_cnt = mcp->mb[6];
2138 if (cur_iocb_cnt)
2139 *cur_iocb_cnt = mcp->mb[7];
2140 if (orig_iocb_cnt)
2141 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002142 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002143 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002144 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002145 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146 }
2147
2148 return (rval);
2149}
2150
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151/*
2152 * qla2x00_get_fcal_position_map
2153 * Get FCAL (LILP) position map using mailbox command
2154 *
2155 * Input:
2156 * ha = adapter state pointer.
2157 * pos_map = buffer pointer (can be NULL).
2158 *
2159 * Returns:
2160 * qla2x00 local function return status code.
2161 *
2162 * Context:
2163 * Kernel context.
2164 */
2165int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002166qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167{
2168 int rval;
2169 mbx_cmd_t mc;
2170 mbx_cmd_t *mcp = &mc;
2171 char *pmap;
2172 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002173 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002175 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2176
Andrew Vasquez4b892582008-09-11 21:22:48 -07002177 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002178 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002179 ql_log(ql_log_warn, vha, 0x1080,
2180 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181 return QLA_MEMORY_ALLOC_FAILED;
2182 }
2183 memset(pmap, 0, FCAL_MAP_SIZE);
2184
2185 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2186 mcp->mb[2] = MSW(pmap_dma);
2187 mcp->mb[3] = LSW(pmap_dma);
2188 mcp->mb[6] = MSW(MSD(pmap_dma));
2189 mcp->mb[7] = LSW(MSD(pmap_dma));
2190 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2191 mcp->in_mb = MBX_1|MBX_0;
2192 mcp->buf_size = FCAL_MAP_SIZE;
2193 mcp->flags = MBX_DMA_IN;
2194 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002195 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196
2197 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002198 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2199 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2200 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2201 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2202 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203
2204 if (pos_map)
2205 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2206 }
2207 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2208
2209 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002210 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002212 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213 }
2214
2215 return rval;
2216}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002217
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002218/*
2219 * qla2x00_get_link_status
2220 *
2221 * Input:
2222 * ha = adapter block pointer.
2223 * loop_id = device loop ID.
2224 * ret_buf = pointer to link status return buffer.
2225 *
2226 * Returns:
2227 * 0 = success.
2228 * BIT_0 = mem alloc error.
2229 * BIT_1 = mailbox error.
2230 */
2231int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002232qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002233 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002234{
2235 int rval;
2236 mbx_cmd_t mc;
2237 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002238 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002239 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002240
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002241 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002242
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002243 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002244 mcp->mb[2] = MSW(stats_dma);
2245 mcp->mb[3] = LSW(stats_dma);
2246 mcp->mb[6] = MSW(MSD(stats_dma));
2247 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002248 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2249 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002250 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002251 mcp->mb[1] = loop_id;
2252 mcp->mb[4] = 0;
2253 mcp->mb[10] = 0;
2254 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2255 mcp->in_mb |= MBX_1;
2256 } else if (HAS_EXTENDED_IDS(ha)) {
2257 mcp->mb[1] = loop_id;
2258 mcp->mb[10] = 0;
2259 mcp->out_mb |= MBX_10|MBX_1;
2260 } else {
2261 mcp->mb[1] = loop_id << 8;
2262 mcp->out_mb |= MBX_1;
2263 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002264 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002265 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002266 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002267
2268 if (rval == QLA_SUCCESS) {
2269 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002270 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2271 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002272 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002273 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002274 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002275 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002276 dwords = offsetof(struct link_statistics, unused1) / 4;
2277 siter = diter = &stats->link_fail_cnt;
2278 while (dwords--)
2279 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002280 }
2281 } else {
2282 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002283 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002284 }
2285
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002286 return rval;
2287}
2288
2289int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002290qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002291 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002292{
2293 int rval;
2294 mbx_cmd_t mc;
2295 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002296 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002297
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002298 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002299
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002300 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002301 mcp->mb[2] = MSW(stats_dma);
2302 mcp->mb[3] = LSW(stats_dma);
2303 mcp->mb[6] = MSW(MSD(stats_dma));
2304 mcp->mb[7] = LSW(MSD(stats_dma));
2305 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002306 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002308 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 -07002309 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002310 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002311 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002312 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002313
2314 if (rval == QLA_SUCCESS) {
2315 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002316 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2317 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002318 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002319 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002320 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002321 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002322 dwords = sizeof(struct link_statistics) / 4;
2323 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002324 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002325 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002326 }
2327 } else {
2328 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002329 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002330 }
2331
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002332 return rval;
2333}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334
2335int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002336qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002337{
2338 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002339 unsigned long flags = 0;
2340
2341 struct abort_entry_24xx *abt;
2342 dma_addr_t abt_dma;
2343 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002344 fc_port_t *fcport = sp->fcport;
2345 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002346 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002347 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002348
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002349 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002350
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002351 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002352 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002353 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002354 break;
2355 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002356 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002357 if (handle == MAX_OUTSTANDING_COMMANDS) {
2358 /* Command not found. */
2359 return QLA_FUNCTION_FAILED;
2360 }
2361
2362 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2363 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002364 ql_log(ql_log_warn, vha, 0x108d,
2365 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002366 return QLA_MEMORY_ALLOC_FAILED;
2367 }
2368 memset(abt, 0, sizeof(struct abort_entry_24xx));
2369
2370 abt->entry_type = ABORT_IOCB_TYPE;
2371 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002372 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002373 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002374 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002375 abt->port_id[0] = fcport->d_id.b.al_pa;
2376 abt->port_id[1] = fcport->d_id.b.area;
2377 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002378 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002379
2380 abt->req_que_no = cpu_to_le16(req->id);
2381
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002382 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002383 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002384 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2385 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002386 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002387 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2388 "Failed to complete IOCB -- error status (%x).\n",
2389 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002390 rval = QLA_FUNCTION_FAILED;
2391 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002392 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2393 "Failed to complete IOCB -- completion status (%x).\n",
2394 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002395 rval = QLA_FUNCTION_FAILED;
2396 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002397 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002398 }
2399
2400 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2401
2402 return rval;
2403}
2404
2405struct tsk_mgmt_cmd {
2406 union {
2407 struct tsk_mgmt_entry tsk;
2408 struct sts_entry_24xx sts;
2409 } p;
2410};
2411
Andrew Vasquez523ec772008-04-03 13:13:24 -07002412static int
2413__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002414 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002415{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002416 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002417 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002418 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002419 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002420 scsi_qla_host_t *vha;
2421 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002422 struct req_que *req;
2423 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002424
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002425 vha = fcport->vha;
2426 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002427 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002428
2429 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2430
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002431 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002432 rsp = ha->rsp_q_map[tag + 1];
2433 else
2434 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002435 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002436 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002437 ql_log(ql_log_warn, vha, 0x1093,
2438 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002439 return QLA_MEMORY_ALLOC_FAILED;
2440 }
2441 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2442
2443 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2444 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002445 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002446 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002447 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002448 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002449 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2450 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2451 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002452 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002453 if (type == TCF_LUN_RESET) {
2454 int_to_scsilun(l, &tsk->p.tsk.lun);
2455 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2456 sizeof(tsk->p.tsk.lun));
2457 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002458
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002459 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002460 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002461 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002462 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2463 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002464 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002465 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2466 "Failed to complete IOCB -- error status (%x).\n",
2467 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002468 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002469 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002470 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002471 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2472 "Failed to complete IOCB -- completion status (%x).\n",
2473 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002474 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002475 } else if (le16_to_cpu(sts->scsi_status) &
2476 SS_RESPONSE_INFO_LEN_VALID) {
2477 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002478 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2479 "Ignoring inconsistent data length -- not enough "
2480 "response info (%d).\n",
2481 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002482 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002483 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2484 "Failed to complete IOCB -- response (%x).\n",
2485 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002486 rval = QLA_FUNCTION_FAILED;
2487 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002488 }
2489
2490 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002491 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002492 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2493 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002494 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2495 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002496 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002497 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002498 }
2499
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002500 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002501
2502 return rval;
2503}
2504
Andrew Vasquez523ec772008-04-03 13:13:24 -07002505int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002506qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002507{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002508 struct qla_hw_data *ha = fcport->vha->hw;
2509
2510 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2511 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2512
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002513 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002514}
2515
2516int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002517qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002518{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002519 struct qla_hw_data *ha = fcport->vha->hw;
2520
2521 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2522 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2523
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002524 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002525}
2526
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002527int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002528qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002529{
2530 int rval;
2531 mbx_cmd_t mc;
2532 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002533 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002534
Andrew Vasquez68af0812008-05-12 22:21:13 -07002535 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002536 return QLA_FUNCTION_FAILED;
2537
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002538 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002539
2540 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2541 mcp->out_mb = MBX_0;
2542 mcp->in_mb = MBX_0;
2543 mcp->tov = 5;
2544 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002545 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002546
2547 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002548 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002549 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002550 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002551 }
2552
2553 return rval;
2554}
2555
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002556/**
2557 * qla2x00_set_serdes_params() -
2558 * @ha: HA context
2559 *
2560 * Returns
2561 */
2562int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002563qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002564 uint16_t sw_em_2g, uint16_t sw_em_4g)
2565{
2566 int rval;
2567 mbx_cmd_t mc;
2568 mbx_cmd_t *mcp = &mc;
2569
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002570 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002571
2572 mcp->mb[0] = MBC_SERDES_PARAMS;
2573 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002574 mcp->mb[2] = sw_em_1g | BIT_15;
2575 mcp->mb[3] = sw_em_2g | BIT_15;
2576 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002577 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2578 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002579 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002580 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002581 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002582
2583 if (rval != QLA_SUCCESS) {
2584 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002585 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2586 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002587 } else {
2588 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002589 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002590 }
2591
2592 return rval;
2593}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002594
2595int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002596qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002597{
2598 int rval;
2599 mbx_cmd_t mc;
2600 mbx_cmd_t *mcp = &mc;
2601
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002602 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002603 return QLA_FUNCTION_FAILED;
2604
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002605 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002606
2607 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002608 mcp->mb[1] = 0;
2609 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002610 mcp->in_mb = MBX_0;
2611 mcp->tov = 5;
2612 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002613 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002614
2615 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002616 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002617 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2618 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002619 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002620 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002621 }
2622
2623 return rval;
2624}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002625
2626int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002627qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002628 uint16_t buffers)
2629{
2630 int rval;
2631 mbx_cmd_t mc;
2632 mbx_cmd_t *mcp = &mc;
2633
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002634 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2635
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002636 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002637 return QLA_FUNCTION_FAILED;
2638
Andrew Vasquez85880802009-12-15 21:29:46 -08002639 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2640 return QLA_FUNCTION_FAILED;
2641
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002642 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002643 mcp->mb[1] = TC_EFT_ENABLE;
2644 mcp->mb[2] = LSW(eft_dma);
2645 mcp->mb[3] = MSW(eft_dma);
2646 mcp->mb[4] = LSW(MSD(eft_dma));
2647 mcp->mb[5] = MSW(MSD(eft_dma));
2648 mcp->mb[6] = buffers;
2649 mcp->mb[7] = TC_AEN_DISABLE;
2650 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 -07002651 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002652 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002653 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002654 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002655 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002656 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2657 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2658 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002659 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002660 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002661 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002662
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002663 return rval;
2664}
2665
2666int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002667qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002668{
2669 int rval;
2670 mbx_cmd_t mc;
2671 mbx_cmd_t *mcp = &mc;
2672
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002673 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2674
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002675 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002676 return QLA_FUNCTION_FAILED;
2677
Andrew Vasquez85880802009-12-15 21:29:46 -08002678 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2679 return QLA_FUNCTION_FAILED;
2680
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002681 mcp->mb[0] = MBC_TRACE_CONTROL;
2682 mcp->mb[1] = TC_EFT_DISABLE;
2683 mcp->out_mb = MBX_1|MBX_0;
2684 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002685 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002686 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002687 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002688 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002689 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2690 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2691 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002692 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002693 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002694 }
2695
2696 return rval;
2697}
2698
Andrew Vasquez88729e52006-06-23 16:10:50 -07002699int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002700qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002701 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2702{
2703 int rval;
2704 mbx_cmd_t mc;
2705 mbx_cmd_t *mcp = &mc;
2706
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002707 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2708
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002709 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2710 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002711 return QLA_FUNCTION_FAILED;
2712
Andrew Vasquez85880802009-12-15 21:29:46 -08002713 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2714 return QLA_FUNCTION_FAILED;
2715
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002716 mcp->mb[0] = MBC_TRACE_CONTROL;
2717 mcp->mb[1] = TC_FCE_ENABLE;
2718 mcp->mb[2] = LSW(fce_dma);
2719 mcp->mb[3] = MSW(fce_dma);
2720 mcp->mb[4] = LSW(MSD(fce_dma));
2721 mcp->mb[5] = MSW(MSD(fce_dma));
2722 mcp->mb[6] = buffers;
2723 mcp->mb[7] = TC_AEN_DISABLE;
2724 mcp->mb[8] = 0;
2725 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2726 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2727 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2728 MBX_1|MBX_0;
2729 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002730 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002731 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002732 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002733 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002734 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2735 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2736 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002737 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002738 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002739
2740 if (mb)
2741 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2742 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002743 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002744 }
2745
2746 return rval;
2747}
2748
2749int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002750qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002751{
2752 int rval;
2753 mbx_cmd_t mc;
2754 mbx_cmd_t *mcp = &mc;
2755
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002756 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2757
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002758 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002759 return QLA_FUNCTION_FAILED;
2760
Andrew Vasquez85880802009-12-15 21:29:46 -08002761 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2762 return QLA_FUNCTION_FAILED;
2763
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002764 mcp->mb[0] = MBC_TRACE_CONTROL;
2765 mcp->mb[1] = TC_FCE_DISABLE;
2766 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2767 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2768 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2769 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002770 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002771 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002772 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002773 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002774 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2775 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2776 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002777 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002778 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002779
2780 if (wr)
2781 *wr = (uint64_t) mcp->mb[5] << 48 |
2782 (uint64_t) mcp->mb[4] << 32 |
2783 (uint64_t) mcp->mb[3] << 16 |
2784 (uint64_t) mcp->mb[2];
2785 if (rd)
2786 *rd = (uint64_t) mcp->mb[9] << 48 |
2787 (uint64_t) mcp->mb[8] << 32 |
2788 (uint64_t) mcp->mb[7] << 16 |
2789 (uint64_t) mcp->mb[6];
2790 }
2791
2792 return rval;
2793}
2794
2795int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002796qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2797 uint16_t *port_speed, uint16_t *mb)
2798{
2799 int rval;
2800 mbx_cmd_t mc;
2801 mbx_cmd_t *mcp = &mc;
2802
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002803 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2804
Giridhar Malavali6e980162010-03-19 17:03:58 -07002805 if (!IS_IIDMA_CAPABLE(vha->hw))
2806 return QLA_FUNCTION_FAILED;
2807
Giridhar Malavali6e980162010-03-19 17:03:58 -07002808 mcp->mb[0] = MBC_PORT_PARAMS;
2809 mcp->mb[1] = loop_id;
2810 mcp->mb[2] = mcp->mb[3] = 0;
2811 mcp->mb[9] = vha->vp_idx;
2812 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2813 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2814 mcp->tov = MBX_TOV_SECONDS;
2815 mcp->flags = 0;
2816 rval = qla2x00_mailbox_command(vha, mcp);
2817
2818 /* Return mailbox statuses. */
2819 if (mb != NULL) {
2820 mb[0] = mcp->mb[0];
2821 mb[1] = mcp->mb[1];
2822 mb[3] = mcp->mb[3];
2823 }
2824
2825 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002826 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002827 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002828 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002829 if (port_speed)
2830 *port_speed = mcp->mb[3];
2831 }
2832
2833 return rval;
2834}
2835
2836int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002837qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002838 uint16_t port_speed, uint16_t *mb)
2839{
2840 int rval;
2841 mbx_cmd_t mc;
2842 mbx_cmd_t *mcp = &mc;
2843
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002844 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2845
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002846 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002847 return QLA_FUNCTION_FAILED;
2848
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002849 mcp->mb[0] = MBC_PORT_PARAMS;
2850 mcp->mb[1] = loop_id;
2851 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002852 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002853 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2854 else
2855 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2856 mcp->mb[9] = vha->vp_idx;
2857 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2858 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002859 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002860 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002861 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002862
2863 /* Return mailbox statuses. */
2864 if (mb != NULL) {
2865 mb[0] = mcp->mb[0];
2866 mb[1] = mcp->mb[1];
2867 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002868 }
2869
2870 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002871 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002872 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002873 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002874 }
2875
2876 return rval;
2877}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002878
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002879void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002880qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002881 struct vp_rpt_id_entry_24xx *rptid_entry)
2882{
2883 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002884 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002885 struct qla_hw_data *ha = vha->hw;
2886 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002887 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002888
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002889 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2890
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002891 if (rptid_entry->entry_status != 0)
2892 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002893
2894 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002895 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2896 "Format 0 : Number of VPs setup %d, number of "
2897 "VPs acquired %d.\n",
2898 MSB(le16_to_cpu(rptid_entry->vp_count)),
2899 LSB(le16_to_cpu(rptid_entry->vp_count)));
2900 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2901 "Primary port id %02x%02x%02x.\n",
2902 rptid_entry->port_id[2], rptid_entry->port_id[1],
2903 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002904 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002905 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002906 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2907 "Format 1: VP[%d] enabled - status %d - with "
2908 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002909 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002910 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002911
2912 vp = vha;
2913 if (vp_idx == 0 && (MSB(stat) != 1))
2914 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002915
Giridhar Malavali882a9172011-11-18 09:03:12 -08002916 if (MSB(stat) != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002917 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2918 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002919 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002920 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002921
Arun Easifeafb7b2010-09-03 14:57:00 -07002922 spin_lock_irqsave(&ha->vport_slock, flags);
2923 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002924 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002925 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002926 spin_unlock_irqrestore(&ha->vport_slock, flags);
2927
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002928 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002929 return;
2930
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002931 vp->d_id.b.domain = rptid_entry->port_id[2];
2932 vp->d_id.b.area = rptid_entry->port_id[1];
2933 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002934
2935 /*
2936 * Cannot configure here as we are still sitting on the
2937 * response queue. Handle it in dpc context.
2938 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002939 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002940
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002941reg_needed:
2942 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2943 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2944 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002945 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002946 }
2947}
2948
2949/*
2950 * qla24xx_modify_vp_config
2951 * Change VP configuration for vha
2952 *
2953 * Input:
2954 * vha = adapter block pointer.
2955 *
2956 * Returns:
2957 * qla2xxx local function return status code.
2958 *
2959 * Context:
2960 * Kernel context.
2961 */
2962int
2963qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2964{
2965 int rval;
2966 struct vp_config_entry_24xx *vpmod;
2967 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002968 struct qla_hw_data *ha = vha->hw;
2969 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002970
2971 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002972
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002973 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2974
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002975 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002976 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002977 ql_log(ql_log_warn, vha, 0x10bc,
2978 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002979 return QLA_MEMORY_ALLOC_FAILED;
2980 }
2981
2982 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2983 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2984 vpmod->entry_count = 1;
2985 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2986 vpmod->vp_count = 1;
2987 vpmod->vp_index1 = vha->vp_idx;
2988 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2989 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2990 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2991 vpmod->entry_count = 1;
2992
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002993 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002994 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002995 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
2996 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002997 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002998 ql_dbg(ql_dbg_mbx, vha, 0x10be,
2999 "Failed to complete IOCB -- error status (%x).\n",
3000 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003001 rval = QLA_FUNCTION_FAILED;
3002 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003003 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3004 "Failed to complete IOCB -- completion status (%x).\n",
3005 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003006 rval = QLA_FUNCTION_FAILED;
3007 } else {
3008 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003009 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003010 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3011 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003012 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003013
3014 return rval;
3015}
3016
3017/*
3018 * qla24xx_control_vp
3019 * Enable a virtual port for given host
3020 *
3021 * Input:
3022 * ha = adapter block pointer.
3023 * vhba = virtual adapter (unused)
3024 * index = index number for enabled VP
3025 *
3026 * Returns:
3027 * qla2xxx local function return status code.
3028 *
3029 * Context:
3030 * Kernel context.
3031 */
3032int
3033qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3034{
3035 int rval;
3036 int map, pos;
3037 struct vp_ctrl_entry_24xx *vce;
3038 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003039 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003040 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003041 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003042
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003043 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3044 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003045
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003046 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003047 return QLA_PARAMETER_ERROR;
3048
3049 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3050 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003051 ql_log(ql_log_warn, vha, 0x10c2,
3052 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003053 return QLA_MEMORY_ALLOC_FAILED;
3054 }
3055 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3056
3057 vce->entry_type = VP_CTRL_IOCB_TYPE;
3058 vce->entry_count = 1;
3059 vce->command = cpu_to_le16(cmd);
3060 vce->vp_count = __constant_cpu_to_le16(1);
3061
3062 /* index map in firmware starts with 1; decrement index
3063 * this is ok as we never use index 0
3064 */
3065 map = (vp_index - 1) / 8;
3066 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003067 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003068 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003069 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003070
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003071 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003072 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003073 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3074 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003075 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003076 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3077 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003078 vce->entry_status);
3079 rval = QLA_FUNCTION_FAILED;
3080 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003081 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3082 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003083 le16_to_cpu(vce->comp_status));
3084 rval = QLA_FUNCTION_FAILED;
3085 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003086 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003087 }
3088
3089 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3090
3091 return rval;
3092}
3093
3094/*
3095 * qla2x00_send_change_request
3096 * Receive or disable RSCN request from fabric controller
3097 *
3098 * Input:
3099 * ha = adapter block pointer
3100 * format = registration format:
3101 * 0 - Reserved
3102 * 1 - Fabric detected registration
3103 * 2 - N_port detected registration
3104 * 3 - Full registration
3105 * FF - clear registration
3106 * vp_idx = Virtual port index
3107 *
3108 * Returns:
3109 * qla2x00 local function return status code.
3110 *
3111 * Context:
3112 * Kernel Context
3113 */
3114
3115int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003116qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003117 uint16_t vp_idx)
3118{
3119 int rval;
3120 mbx_cmd_t mc;
3121 mbx_cmd_t *mcp = &mc;
3122
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003123 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3124
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003125 /*
3126 * This command is implicitly executed by firmware during login for the
3127 * physical hosts
3128 */
3129 if (vp_idx == 0)
3130 return QLA_FUNCTION_FAILED;
3131
3132 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3133 mcp->mb[1] = format;
3134 mcp->mb[9] = vp_idx;
3135 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3136 mcp->in_mb = MBX_0|MBX_1;
3137 mcp->tov = MBX_TOV_SECONDS;
3138 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003139 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003140
3141 if (rval == QLA_SUCCESS) {
3142 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3143 rval = BIT_1;
3144 }
3145 } else
3146 rval = BIT_1;
3147
3148 return rval;
3149}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003150
3151int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003152qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003153 uint32_t size)
3154{
3155 int rval;
3156 mbx_cmd_t mc;
3157 mbx_cmd_t *mcp = &mc;
3158
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003159 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003160
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003161 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003162 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3163 mcp->mb[8] = MSW(addr);
3164 mcp->out_mb = MBX_8|MBX_0;
3165 } else {
3166 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3167 mcp->out_mb = MBX_0;
3168 }
3169 mcp->mb[1] = LSW(addr);
3170 mcp->mb[2] = MSW(req_dma);
3171 mcp->mb[3] = LSW(req_dma);
3172 mcp->mb[6] = MSW(MSD(req_dma));
3173 mcp->mb[7] = LSW(MSD(req_dma));
3174 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003175 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003176 mcp->mb[4] = MSW(size);
3177 mcp->mb[5] = LSW(size);
3178 mcp->out_mb |= MBX_5|MBX_4;
3179 } else {
3180 mcp->mb[4] = LSW(size);
3181 mcp->out_mb |= MBX_4;
3182 }
3183
3184 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003185 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003186 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003187 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003188
3189 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003190 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3191 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003192 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003193 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003194 }
3195
3196 return rval;
3197}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003198
3199/* 84XX Support **************************************************************/
3200
3201struct cs84xx_mgmt_cmd {
3202 union {
3203 struct verify_chip_entry_84xx req;
3204 struct verify_chip_rsp_84xx rsp;
3205 } p;
3206};
3207
3208int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003209qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003210{
3211 int rval, retry;
3212 struct cs84xx_mgmt_cmd *mn;
3213 dma_addr_t mn_dma;
3214 uint16_t options;
3215 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003216 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003217
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003218 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003219
3220 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3221 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003222 return QLA_MEMORY_ALLOC_FAILED;
3223 }
3224
3225 /* Force Update? */
3226 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3227 /* Diagnostic firmware? */
3228 /* options |= MENLO_DIAG_FW; */
3229 /* We update the firmware with only one data sequence. */
3230 options |= VCO_END_OF_DATA;
3231
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003232 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003233 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003234 memset(mn, 0, sizeof(*mn));
3235 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3236 mn->p.req.entry_count = 1;
3237 mn->p.req.options = cpu_to_le16(options);
3238
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003239 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3240 "Dump of Verify Request.\n");
3241 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3242 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003243
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003244 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003245 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003246 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3247 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003248 goto verify_done;
3249 }
3250
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003251 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3252 "Dump of Verify Response.\n");
3253 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3254 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003255
3256 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3257 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3258 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003259 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3260 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003261
3262 if (status[0] != CS_COMPLETE) {
3263 rval = QLA_FUNCTION_FAILED;
3264 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003265 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3266 "Firmware update failed. Retrying "
3267 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003268 options |= VCO_DONT_UPDATE_FW;
3269 options &= ~VCO_FORCE_UPDATE;
3270 retry = 1;
3271 }
3272 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003273 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3274 "Firmware updated to %x.\n",
3275 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003276
3277 /* NOTE: we only update OP firmware. */
3278 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3279 ha->cs84xx->op_fw_version =
3280 le32_to_cpu(mn->p.rsp.fw_ver);
3281 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3282 flags);
3283 }
3284 } while (retry);
3285
3286verify_done:
3287 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3288
3289 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003290 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003291 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003292 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003293 }
3294
3295 return rval;
3296}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003297
3298int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003299qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003300{
3301 int rval;
3302 unsigned long flags;
3303 mbx_cmd_t mc;
3304 mbx_cmd_t *mcp = &mc;
3305 struct device_reg_25xxmq __iomem *reg;
3306 struct qla_hw_data *ha = vha->hw;
3307
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003308 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3309
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003310 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003311 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003312 mcp->mb[2] = MSW(LSD(req->dma));
3313 mcp->mb[3] = LSW(LSD(req->dma));
3314 mcp->mb[6] = MSW(MSD(req->dma));
3315 mcp->mb[7] = LSW(MSD(req->dma));
3316 mcp->mb[5] = req->length;
3317 if (req->rsp)
3318 mcp->mb[10] = req->rsp->id;
3319 mcp->mb[12] = req->qos;
3320 mcp->mb[11] = req->vp_idx;
3321 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003322 if (IS_QLA83XX(ha))
3323 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003324
3325 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3326 QLA_QUE_PAGE * req->id);
3327
3328 mcp->mb[4] = req->id;
3329 /* que in ptr index */
3330 mcp->mb[8] = 0;
3331 /* que out ptr index */
3332 mcp->mb[9] = 0;
3333 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3334 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3335 mcp->in_mb = MBX_0;
3336 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003337 mcp->tov = MBX_TOV_SECONDS * 2;
3338
3339 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3340 mcp->in_mb |= MBX_1;
3341 if (IS_QLA83XX(ha)) {
3342 mcp->out_mb |= MBX_15;
3343 /* debug q create issue in SR-IOV */
3344 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3345 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003346
3347 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003348 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003349 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003350 if (!IS_QLA83XX(ha))
3351 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003352 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003353 req->req_q_in = &reg->req_q_in;
3354 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003355 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3356
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003357 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003358 if (rval != QLA_SUCCESS) {
3359 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3360 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3361 } else {
3362 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3363 }
3364
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003365 return rval;
3366}
3367
3368int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003369qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003370{
3371 int rval;
3372 unsigned long flags;
3373 mbx_cmd_t mc;
3374 mbx_cmd_t *mcp = &mc;
3375 struct device_reg_25xxmq __iomem *reg;
3376 struct qla_hw_data *ha = vha->hw;
3377
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003378 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3379
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003380 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003381 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003382 mcp->mb[2] = MSW(LSD(rsp->dma));
3383 mcp->mb[3] = LSW(LSD(rsp->dma));
3384 mcp->mb[6] = MSW(MSD(rsp->dma));
3385 mcp->mb[7] = LSW(MSD(rsp->dma));
3386 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003387 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003388 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003389 if (IS_QLA83XX(ha))
3390 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003391
3392 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3393 QLA_QUE_PAGE * rsp->id);
3394
3395 mcp->mb[4] = rsp->id;
3396 /* que in ptr index */
3397 mcp->mb[8] = 0;
3398 /* que out ptr index */
3399 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003400 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003401 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3402 mcp->in_mb = MBX_0;
3403 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003404 mcp->tov = MBX_TOV_SECONDS * 2;
3405
3406 if (IS_QLA81XX(ha)) {
3407 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3408 mcp->in_mb |= MBX_1;
3409 } else if (IS_QLA83XX(ha)) {
3410 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3411 mcp->in_mb |= MBX_1;
3412 /* debug q create issue in SR-IOV */
3413 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3414 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003415
3416 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003417 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003418 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003419 if (!IS_QLA83XX(ha))
3420 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003421 }
3422
3423 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3424
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003425 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003426 if (rval != QLA_SUCCESS) {
3427 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3428 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3429 } else {
3430 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3431 }
3432
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003433 return rval;
3434}
3435
Andrew Vasquez8a659572009-02-08 20:50:12 -08003436int
3437qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3438{
3439 int rval;
3440 mbx_cmd_t mc;
3441 mbx_cmd_t *mcp = &mc;
3442
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003443 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003444
3445 mcp->mb[0] = MBC_IDC_ACK;
3446 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3447 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3448 mcp->in_mb = MBX_0;
3449 mcp->tov = MBX_TOV_SECONDS;
3450 mcp->flags = 0;
3451 rval = qla2x00_mailbox_command(vha, mcp);
3452
3453 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003454 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3455 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003456 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003457 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003458 }
3459
3460 return rval;
3461}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003462
3463int
3464qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3465{
3466 int rval;
3467 mbx_cmd_t mc;
3468 mbx_cmd_t *mcp = &mc;
3469
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003470 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3471
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003472 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003473 return QLA_FUNCTION_FAILED;
3474
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003475 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3476 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3477 mcp->out_mb = MBX_1|MBX_0;
3478 mcp->in_mb = MBX_1|MBX_0;
3479 mcp->tov = MBX_TOV_SECONDS;
3480 mcp->flags = 0;
3481 rval = qla2x00_mailbox_command(vha, mcp);
3482
3483 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003484 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3485 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3486 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003487 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003488 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003489 *sector_size = mcp->mb[1];
3490 }
3491
3492 return rval;
3493}
3494
3495int
3496qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3497{
3498 int rval;
3499 mbx_cmd_t mc;
3500 mbx_cmd_t *mcp = &mc;
3501
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003502 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003503 return QLA_FUNCTION_FAILED;
3504
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003505 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003506
3507 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3508 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3509 FAC_OPT_CMD_WRITE_PROTECT;
3510 mcp->out_mb = MBX_1|MBX_0;
3511 mcp->in_mb = MBX_1|MBX_0;
3512 mcp->tov = MBX_TOV_SECONDS;
3513 mcp->flags = 0;
3514 rval = qla2x00_mailbox_command(vha, mcp);
3515
3516 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003517 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3518 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3519 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003520 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003521 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003522 }
3523
3524 return rval;
3525}
3526
3527int
3528qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3529{
3530 int rval;
3531 mbx_cmd_t mc;
3532 mbx_cmd_t *mcp = &mc;
3533
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003534 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003535 return QLA_FUNCTION_FAILED;
3536
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003537 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003538
3539 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3540 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3541 mcp->mb[2] = LSW(start);
3542 mcp->mb[3] = MSW(start);
3543 mcp->mb[4] = LSW(finish);
3544 mcp->mb[5] = MSW(finish);
3545 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3546 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3547 mcp->tov = MBX_TOV_SECONDS;
3548 mcp->flags = 0;
3549 rval = qla2x00_mailbox_command(vha, mcp);
3550
3551 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003552 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3553 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3554 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003555 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003556 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003557 }
3558
3559 return rval;
3560}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003561
3562int
3563qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3564{
3565 int rval = 0;
3566 mbx_cmd_t mc;
3567 mbx_cmd_t *mcp = &mc;
3568
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003569 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003570
3571 mcp->mb[0] = MBC_RESTART_MPI_FW;
3572 mcp->out_mb = MBX_0;
3573 mcp->in_mb = MBX_0|MBX_1;
3574 mcp->tov = MBX_TOV_SECONDS;
3575 mcp->flags = 0;
3576 rval = qla2x00_mailbox_command(vha, mcp);
3577
3578 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003579 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3580 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3581 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003582 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003583 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003584 }
3585
3586 return rval;
3587}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003588
3589int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003590qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3591 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003592{
3593 int rval;
3594 mbx_cmd_t mc;
3595 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003596 struct qla_hw_data *ha = vha->hw;
3597
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003598 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3599
Joe Carnuccio6766df92011-05-10 11:30:15 -07003600 if (!IS_FWI2_CAPABLE(ha))
3601 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003602
Joe Carnuccio6766df92011-05-10 11:30:15 -07003603 if (len == 1)
3604 opt |= BIT_0;
3605
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003606 mcp->mb[0] = MBC_READ_SFP;
3607 mcp->mb[1] = dev;
3608 mcp->mb[2] = MSW(sfp_dma);
3609 mcp->mb[3] = LSW(sfp_dma);
3610 mcp->mb[6] = MSW(MSD(sfp_dma));
3611 mcp->mb[7] = LSW(MSD(sfp_dma));
3612 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003613 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003614 mcp->mb[10] = opt;
3615 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 -07003616 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003617 mcp->tov = MBX_TOV_SECONDS;
3618 mcp->flags = 0;
3619 rval = qla2x00_mailbox_command(vha, mcp);
3620
3621 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003622 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003623
3624 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003625 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3626 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003627 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003628 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003629 }
3630
3631 return rval;
3632}
3633
3634int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003635qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3636 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003637{
3638 int rval;
3639 mbx_cmd_t mc;
3640 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003641 struct qla_hw_data *ha = vha->hw;
3642
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003643 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3644
Joe Carnuccio6766df92011-05-10 11:30:15 -07003645 if (!IS_FWI2_CAPABLE(ha))
3646 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003647
Joe Carnuccio6766df92011-05-10 11:30:15 -07003648 if (len == 1)
3649 opt |= BIT_0;
3650
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003651 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003652 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003653
3654 mcp->mb[0] = MBC_WRITE_SFP;
3655 mcp->mb[1] = dev;
3656 mcp->mb[2] = MSW(sfp_dma);
3657 mcp->mb[3] = LSW(sfp_dma);
3658 mcp->mb[6] = MSW(MSD(sfp_dma));
3659 mcp->mb[7] = LSW(MSD(sfp_dma));
3660 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003661 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003662 mcp->mb[10] = opt;
3663 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 -07003664 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003665 mcp->tov = MBX_TOV_SECONDS;
3666 mcp->flags = 0;
3667 rval = qla2x00_mailbox_command(vha, mcp);
3668
3669 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003670 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3671 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003672 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003673 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003674 }
3675
3676 return rval;
3677}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003678
3679int
3680qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3681 uint16_t size_in_bytes, uint16_t *actual_size)
3682{
3683 int rval;
3684 mbx_cmd_t mc;
3685 mbx_cmd_t *mcp = &mc;
3686
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003687 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3688
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003689 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003690 return QLA_FUNCTION_FAILED;
3691
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003692 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3693 mcp->mb[2] = MSW(stats_dma);
3694 mcp->mb[3] = LSW(stats_dma);
3695 mcp->mb[6] = MSW(MSD(stats_dma));
3696 mcp->mb[7] = LSW(MSD(stats_dma));
3697 mcp->mb[8] = size_in_bytes >> 2;
3698 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3699 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3700 mcp->tov = MBX_TOV_SECONDS;
3701 mcp->flags = 0;
3702 rval = qla2x00_mailbox_command(vha, mcp);
3703
3704 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003705 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3706 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3707 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003708 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003709 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3710
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003711
3712 *actual_size = mcp->mb[2] << 2;
3713 }
3714
3715 return rval;
3716}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003717
3718int
3719qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3720 uint16_t size)
3721{
3722 int rval;
3723 mbx_cmd_t mc;
3724 mbx_cmd_t *mcp = &mc;
3725
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003726 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3727
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003728 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003729 return QLA_FUNCTION_FAILED;
3730
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003731 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3732 mcp->mb[1] = 0;
3733 mcp->mb[2] = MSW(tlv_dma);
3734 mcp->mb[3] = LSW(tlv_dma);
3735 mcp->mb[6] = MSW(MSD(tlv_dma));
3736 mcp->mb[7] = LSW(MSD(tlv_dma));
3737 mcp->mb[8] = size;
3738 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3739 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3740 mcp->tov = MBX_TOV_SECONDS;
3741 mcp->flags = 0;
3742 rval = qla2x00_mailbox_command(vha, mcp);
3743
3744 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003745 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3746 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3747 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003748 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003749 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003750 }
3751
3752 return rval;
3753}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003754
3755int
3756qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3757{
3758 int rval;
3759 mbx_cmd_t mc;
3760 mbx_cmd_t *mcp = &mc;
3761
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003762 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3763
Andrew Vasquez18e75552009-06-03 09:55:30 -07003764 if (!IS_FWI2_CAPABLE(vha->hw))
3765 return QLA_FUNCTION_FAILED;
3766
Andrew Vasquez18e75552009-06-03 09:55:30 -07003767 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3768 mcp->mb[1] = LSW(risc_addr);
3769 mcp->mb[8] = MSW(risc_addr);
3770 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3771 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3772 mcp->tov = 30;
3773 mcp->flags = 0;
3774 rval = qla2x00_mailbox_command(vha, mcp);
3775 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003776 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3777 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003778 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003779 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003780 *data = mcp->mb[3] << 16 | mcp->mb[2];
3781 }
3782
3783 return rval;
3784}
3785
3786int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003787qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3788 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003789{
3790 int rval;
3791 mbx_cmd_t mc;
3792 mbx_cmd_t *mcp = &mc;
3793 uint32_t iter_cnt = 0x1;
3794
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003795 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003796
3797 memset(mcp->mb, 0 , sizeof(mcp->mb));
3798 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3799 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3800
3801 /* transfer count */
3802 mcp->mb[10] = LSW(mreq->transfer_size);
3803 mcp->mb[11] = MSW(mreq->transfer_size);
3804
3805 /* send data address */
3806 mcp->mb[14] = LSW(mreq->send_dma);
3807 mcp->mb[15] = MSW(mreq->send_dma);
3808 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3809 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3810
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003811 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003812 mcp->mb[16] = LSW(mreq->rcv_dma);
3813 mcp->mb[17] = MSW(mreq->rcv_dma);
3814 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3815 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3816
3817 /* Iteration count */
3818 mcp->mb[18] = LSW(iter_cnt);
3819 mcp->mb[19] = MSW(iter_cnt);
3820
3821 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3822 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003823 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003824 mcp->out_mb |= MBX_2;
3825 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3826
3827 mcp->buf_size = mreq->transfer_size;
3828 mcp->tov = MBX_TOV_SECONDS;
3829 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3830
3831 rval = qla2x00_mailbox_command(vha, mcp);
3832
3833 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003834 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3835 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3836 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3837 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003838 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003839 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003840 }
3841
3842 /* Copy mailbox information */
3843 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003844 return rval;
3845}
3846
3847int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003848qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3849 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003850{
3851 int rval;
3852 mbx_cmd_t mc;
3853 mbx_cmd_t *mcp = &mc;
3854 struct qla_hw_data *ha = vha->hw;
3855
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003856 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003857
3858 memset(mcp->mb, 0 , sizeof(mcp->mb));
3859 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3860 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003861 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003862 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003863 mcp->mb[2] = vha->fcoe_fcf_idx;
3864 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003865 mcp->mb[16] = LSW(mreq->rcv_dma);
3866 mcp->mb[17] = MSW(mreq->rcv_dma);
3867 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3868 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3869
3870 mcp->mb[10] = LSW(mreq->transfer_size);
3871
3872 mcp->mb[14] = LSW(mreq->send_dma);
3873 mcp->mb[15] = MSW(mreq->send_dma);
3874 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3875 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3876
3877 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3878 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003879 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003880 mcp->out_mb |= MBX_2;
3881
3882 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003883 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
3884 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003885 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003886 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003887 mcp->in_mb |= MBX_3;
3888
3889 mcp->tov = MBX_TOV_SECONDS;
3890 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3891 mcp->buf_size = mreq->transfer_size;
3892
3893 rval = qla2x00_mailbox_command(vha, mcp);
3894
3895 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003896 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3897 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3898 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003899 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003900 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003901 }
3902
3903 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003904 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003905 return rval;
3906}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003907
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003908int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003909qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003910{
3911 int rval;
3912 mbx_cmd_t mc;
3913 mbx_cmd_t *mcp = &mc;
3914
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003915 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3916 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003917
3918 mcp->mb[0] = MBC_ISP84XX_RESET;
3919 mcp->mb[1] = enable_diagnostic;
3920 mcp->out_mb = MBX_1|MBX_0;
3921 mcp->in_mb = MBX_1|MBX_0;
3922 mcp->tov = MBX_TOV_SECONDS;
3923 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003924 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003925
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003926 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003927 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003928 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003929 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003930
3931 return rval;
3932}
3933
3934int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003935qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3936{
3937 int rval;
3938 mbx_cmd_t mc;
3939 mbx_cmd_t *mcp = &mc;
3940
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003941 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3942
Andrew Vasquez18e75552009-06-03 09:55:30 -07003943 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003944 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003945
Andrew Vasquez18e75552009-06-03 09:55:30 -07003946 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3947 mcp->mb[1] = LSW(risc_addr);
3948 mcp->mb[2] = LSW(data);
3949 mcp->mb[3] = MSW(data);
3950 mcp->mb[8] = MSW(risc_addr);
3951 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3952 mcp->in_mb = MBX_0;
3953 mcp->tov = 30;
3954 mcp->flags = 0;
3955 rval = qla2x00_mailbox_command(vha, mcp);
3956 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003957 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3958 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003959 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003960 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003961 }
3962
3963 return rval;
3964}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003965
3966int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003967qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3968{
3969 int rval;
3970 uint32_t stat, timer;
3971 uint16_t mb0 = 0;
3972 struct qla_hw_data *ha = vha->hw;
3973 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3974
3975 rval = QLA_SUCCESS;
3976
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003977 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003978
3979 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3980
3981 /* Write the MBC data to the registers */
3982 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3983 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3984 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3985 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3986 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3987
3988 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3989
3990 /* Poll for MBC interrupt */
3991 for (timer = 6000000; timer; timer--) {
3992 /* Check for pending interrupts. */
3993 stat = RD_REG_DWORD(&reg->host_status);
3994 if (stat & HSRX_RISC_INT) {
3995 stat &= 0xff;
3996
3997 if (stat == 0x1 || stat == 0x2 ||
3998 stat == 0x10 || stat == 0x11) {
3999 set_bit(MBX_INTERRUPT,
4000 &ha->mbx_cmd_flags);
4001 mb0 = RD_REG_WORD(&reg->mailbox0);
4002 WRT_REG_DWORD(&reg->hccr,
4003 HCCRX_CLR_RISC_INT);
4004 RD_REG_DWORD(&reg->hccr);
4005 break;
4006 }
4007 }
4008 udelay(5);
4009 }
4010
4011 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4012 rval = mb0 & MBS_MASK;
4013 else
4014 rval = QLA_FUNCTION_FAILED;
4015
4016 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004017 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4018 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004019 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004020 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004021 }
4022
4023 return rval;
4024}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004025
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004026int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004027qla2x00_get_data_rate(scsi_qla_host_t *vha)
4028{
4029 int rval;
4030 mbx_cmd_t mc;
4031 mbx_cmd_t *mcp = &mc;
4032 struct qla_hw_data *ha = vha->hw;
4033
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004034 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
4035
Michael Hernandez3064ff32009-12-15 21:29:44 -08004036 if (!IS_FWI2_CAPABLE(ha))
4037 return QLA_FUNCTION_FAILED;
4038
Michael Hernandez3064ff32009-12-15 21:29:44 -08004039 mcp->mb[0] = MBC_DATA_RATE;
4040 mcp->mb[1] = 0;
4041 mcp->out_mb = MBX_1|MBX_0;
4042 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004043 if (IS_QLA83XX(ha))
4044 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004045 mcp->tov = MBX_TOV_SECONDS;
4046 mcp->flags = 0;
4047 rval = qla2x00_mailbox_command(vha, mcp);
4048 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004049 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4050 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004051 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004052 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004053 if (mcp->mb[1] != 0x7)
4054 ha->link_data_rate = mcp->mb[1];
4055 }
4056
4057 return rval;
4058}
Sarang Radke09ff7012010-03-19 17:03:59 -07004059
4060int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004061qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4062{
4063 int rval;
4064 mbx_cmd_t mc;
4065 mbx_cmd_t *mcp = &mc;
4066 struct qla_hw_data *ha = vha->hw;
4067
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004068 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004069
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004070 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004071 return QLA_FUNCTION_FAILED;
4072 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4073 mcp->out_mb = MBX_0;
4074 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4075 mcp->tov = MBX_TOV_SECONDS;
4076 mcp->flags = 0;
4077
4078 rval = qla2x00_mailbox_command(vha, mcp);
4079
4080 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004081 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4082 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004083 } else {
4084 /* Copy all bits to preserve original value */
4085 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4086
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004087 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004088 }
4089 return rval;
4090}
4091
4092int
4093qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4094{
4095 int rval;
4096 mbx_cmd_t mc;
4097 mbx_cmd_t *mcp = &mc;
4098
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004099 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004100
4101 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4102 /* Copy all bits to preserve original setting */
4103 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4104 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4105 mcp->in_mb = MBX_0;
4106 mcp->tov = MBX_TOV_SECONDS;
4107 mcp->flags = 0;
4108 rval = qla2x00_mailbox_command(vha, mcp);
4109
4110 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004111 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4112 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004113 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004114 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004115
4116 return rval;
4117}
4118
4119
4120int
Sarang Radke09ff7012010-03-19 17:03:59 -07004121qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4122 uint16_t *mb)
4123{
4124 int rval;
4125 mbx_cmd_t mc;
4126 mbx_cmd_t *mcp = &mc;
4127 struct qla_hw_data *ha = vha->hw;
4128
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004129 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4130
Sarang Radke09ff7012010-03-19 17:03:59 -07004131 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4132 return QLA_FUNCTION_FAILED;
4133
Sarang Radke09ff7012010-03-19 17:03:59 -07004134 mcp->mb[0] = MBC_PORT_PARAMS;
4135 mcp->mb[1] = loop_id;
4136 if (ha->flags.fcp_prio_enabled)
4137 mcp->mb[2] = BIT_1;
4138 else
4139 mcp->mb[2] = BIT_2;
4140 mcp->mb[4] = priority & 0xf;
4141 mcp->mb[9] = vha->vp_idx;
4142 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4143 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4144 mcp->tov = 30;
4145 mcp->flags = 0;
4146 rval = qla2x00_mailbox_command(vha, mcp);
4147 if (mb != NULL) {
4148 mb[0] = mcp->mb[0];
4149 mb[1] = mcp->mb[1];
4150 mb[3] = mcp->mb[3];
4151 mb[4] = mcp->mb[4];
4152 }
4153
4154 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004155 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004156 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004157 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004158 }
4159
4160 return rval;
4161}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004162
4163int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004164qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4165{
4166 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004167 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004168 struct qla_hw_data *ha = vha->hw;
4169
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004170 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004171
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004172 /* Integer part */
4173 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004174 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004175 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004176 ha->flags.thermal_supported = 0;
4177 goto fail;
4178 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004179 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004180
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004181 /* Fraction part */
4182 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004183 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004184 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004185 ha->flags.thermal_supported = 0;
4186 goto fail;
4187 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004188 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004189
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004190 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004191fail:
4192 return rval;
4193}
4194
4195int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004196qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4197{
4198 int rval;
4199 struct qla_hw_data *ha = vha->hw;
4200 mbx_cmd_t mc;
4201 mbx_cmd_t *mcp = &mc;
4202
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004203 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4204
Giridhar Malavalia9083012010-04-12 17:59:55 -07004205 if (!IS_FWI2_CAPABLE(ha))
4206 return QLA_FUNCTION_FAILED;
4207
Giridhar Malavalia9083012010-04-12 17:59:55 -07004208 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004209 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004210 mcp->mb[1] = 1;
4211
4212 mcp->out_mb = MBX_1|MBX_0;
4213 mcp->in_mb = MBX_0;
4214 mcp->tov = 30;
4215 mcp->flags = 0;
4216
4217 rval = qla2x00_mailbox_command(vha, mcp);
4218 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004219 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4220 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004221 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004222 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004223 }
4224
4225 return rval;
4226}
4227
4228int
4229qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4230{
4231 int rval;
4232 struct qla_hw_data *ha = vha->hw;
4233 mbx_cmd_t mc;
4234 mbx_cmd_t *mcp = &mc;
4235
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004236 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4237
Giridhar Malavalia9083012010-04-12 17:59:55 -07004238 if (!IS_QLA82XX(ha))
4239 return QLA_FUNCTION_FAILED;
4240
Giridhar Malavalia9083012010-04-12 17:59:55 -07004241 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004242 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004243 mcp->mb[1] = 0;
4244
4245 mcp->out_mb = MBX_1|MBX_0;
4246 mcp->in_mb = MBX_0;
4247 mcp->tov = 30;
4248 mcp->flags = 0;
4249
4250 rval = qla2x00_mailbox_command(vha, mcp);
4251 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004252 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4253 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004254 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004255 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004256 }
4257
4258 return rval;
4259}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004260
4261int
4262qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4263{
4264 struct qla_hw_data *ha = vha->hw;
4265 mbx_cmd_t mc;
4266 mbx_cmd_t *mcp = &mc;
4267 int rval = QLA_FUNCTION_FAILED;
4268
4269 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4270
4271 memset(mcp->mb, 0 , sizeof(mcp->mb));
4272 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4273 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4274 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4275 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4276
4277 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4278 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4279 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4280
4281 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4282 mcp->tov = MBX_TOV_SECONDS;
4283 rval = qla2x00_mailbox_command(vha, mcp);
4284
4285 /* Always copy back return mailbox values. */
4286 if (rval != QLA_SUCCESS) {
4287 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4288 "mailbox command FAILED=0x%x, subcode=%x.\n",
4289 (mcp->mb[1] << 16) | mcp->mb[0],
4290 (mcp->mb[3] << 16) | mcp->mb[2]);
4291 } else {
4292 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4293 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4294 if (!ha->md_template_size) {
4295 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4296 "Null template size obtained.\n");
4297 rval = QLA_FUNCTION_FAILED;
4298 }
4299 }
4300 return rval;
4301}
4302
4303int
4304qla82xx_md_get_template(scsi_qla_host_t *vha)
4305{
4306 struct qla_hw_data *ha = vha->hw;
4307 mbx_cmd_t mc;
4308 mbx_cmd_t *mcp = &mc;
4309 int rval = QLA_FUNCTION_FAILED;
4310
4311 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4312
4313 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4314 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4315 if (!ha->md_tmplt_hdr) {
4316 ql_log(ql_log_warn, vha, 0x1124,
4317 "Unable to allocate memory for Minidump template.\n");
4318 return rval;
4319 }
4320
4321 memset(mcp->mb, 0 , sizeof(mcp->mb));
4322 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4323 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4324 mcp->mb[2] = LSW(RQST_TMPLT);
4325 mcp->mb[3] = MSW(RQST_TMPLT);
4326 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4327 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4328 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4329 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4330 mcp->mb[8] = LSW(ha->md_template_size);
4331 mcp->mb[9] = MSW(ha->md_template_size);
4332
4333 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4334 mcp->tov = MBX_TOV_SECONDS;
4335 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4336 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4337 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4338 rval = qla2x00_mailbox_command(vha, mcp);
4339
4340 if (rval != QLA_SUCCESS) {
4341 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4342 "mailbox command FAILED=0x%x, subcode=%x.\n",
4343 ((mcp->mb[1] << 16) | mcp->mb[0]),
4344 ((mcp->mb[3] << 16) | mcp->mb[2]));
4345 } else
4346 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4347 return rval;
4348}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004349
4350int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004351qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4352{
4353 int rval;
4354 struct qla_hw_data *ha = vha->hw;
4355 mbx_cmd_t mc;
4356 mbx_cmd_t *mcp = &mc;
4357
4358 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4359 return QLA_FUNCTION_FAILED;
4360
4361 ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
4362
4363 memset(mcp, 0, sizeof(mbx_cmd_t));
4364 mcp->mb[0] = MBC_SET_LED_CONFIG;
4365 mcp->mb[1] = led_cfg[0];
4366 mcp->mb[2] = led_cfg[1];
4367 if (IS_QLA8031(ha)) {
4368 mcp->mb[3] = led_cfg[2];
4369 mcp->mb[4] = led_cfg[3];
4370 mcp->mb[5] = led_cfg[4];
4371 mcp->mb[6] = led_cfg[5];
4372 }
4373
4374 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4375 if (IS_QLA8031(ha))
4376 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4377 mcp->in_mb = MBX_0;
4378 mcp->tov = 30;
4379 mcp->flags = 0;
4380
4381 rval = qla2x00_mailbox_command(vha, mcp);
4382 if (rval != QLA_SUCCESS) {
4383 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4384 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4385 } else {
4386 ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
4387 }
4388
4389 return rval;
4390}
4391
4392int
4393qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4394{
4395 int rval;
4396 struct qla_hw_data *ha = vha->hw;
4397 mbx_cmd_t mc;
4398 mbx_cmd_t *mcp = &mc;
4399
4400 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4401 return QLA_FUNCTION_FAILED;
4402
4403 ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
4404
4405 memset(mcp, 0, sizeof(mbx_cmd_t));
4406 mcp->mb[0] = MBC_GET_LED_CONFIG;
4407
4408 mcp->out_mb = MBX_0;
4409 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4410 if (IS_QLA8031(ha))
4411 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4412 mcp->tov = 30;
4413 mcp->flags = 0;
4414
4415 rval = qla2x00_mailbox_command(vha, mcp);
4416 if (rval != QLA_SUCCESS) {
4417 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4418 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4419 } else {
4420 led_cfg[0] = mcp->mb[1];
4421 led_cfg[1] = mcp->mb[2];
4422 if (IS_QLA8031(ha)) {
4423 led_cfg[2] = mcp->mb[3];
4424 led_cfg[3] = mcp->mb[4];
4425 led_cfg[4] = mcp->mb[5];
4426 led_cfg[5] = mcp->mb[6];
4427 }
4428 ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
4429 }
4430
4431 return rval;
4432}
4433
4434int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004435qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4436{
4437 int rval;
4438 struct qla_hw_data *ha = vha->hw;
4439 mbx_cmd_t mc;
4440 mbx_cmd_t *mcp = &mc;
4441
4442 if (!IS_QLA82XX(ha))
4443 return QLA_FUNCTION_FAILED;
4444
4445 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4446 "Entered %s.\n", __func__);
4447
4448 memset(mcp, 0, sizeof(mbx_cmd_t));
4449 mcp->mb[0] = MBC_SET_LED_CONFIG;
4450 if (enable)
4451 mcp->mb[7] = 0xE;
4452 else
4453 mcp->mb[7] = 0xD;
4454
4455 mcp->out_mb = MBX_7|MBX_0;
4456 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004457 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004458 mcp->flags = 0;
4459
4460 rval = qla2x00_mailbox_command(vha, mcp);
4461 if (rval != QLA_SUCCESS) {
4462 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4463 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4464 } else {
4465 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4466 "Done %s.\n", __func__);
4467 }
4468
4469 return rval;
4470}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004471
4472int
4473qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4474{
4475 int rval;
4476 struct qla_hw_data *ha = vha->hw;
4477 mbx_cmd_t mc;
4478 mbx_cmd_t *mcp = &mc;
4479
4480 if (!IS_QLA83XX(ha))
4481 return QLA_FUNCTION_FAILED;
4482
4483 ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
4484
4485 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4486 mcp->mb[1] = LSW(reg);
4487 mcp->mb[2] = MSW(reg);
4488 mcp->mb[3] = LSW(data);
4489 mcp->mb[4] = MSW(data);
4490 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4491
4492 mcp->in_mb = MBX_1|MBX_0;
4493 mcp->tov = MBX_TOV_SECONDS;
4494 mcp->flags = 0;
4495 rval = qla2x00_mailbox_command(vha, mcp);
4496
4497 if (rval != QLA_SUCCESS) {
4498 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4499 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4500 } else {
4501 ql_dbg(ql_dbg_mbx, vha, 0x1132,
4502 "Done %s.\n", __func__);
4503 }
4504 return rval;
4505}